0

Consider this document:

{
 "id":1,
 "name":"A",
 "lastName":"AA",
 "friends":{
   "f1":{"name":"X", "lastName":"XX"},
   "f2":{"name":"Y", "lastName":"YY"}
  }
}

I would like to search for friend with name "Y", but without knowing that the key is "f2"... the key could be anything. I know that I could set "friends" as an array, but I don't want to do so.

1
  • without f1 or f2 not possible Commented May 16, 2018 at 9:03

1 Answer 1

1

There you go:

db.collection.aggregate({
    $addFields: {
        "friends": {
            $arrayToObject: { // transform the array of key-value pairs back into a subdocument
                $filter: {
                    input: {
                        $objectToArray: "$friends" // transform the "friends" subdocument into an array of key-value pairs
                    },
                    as: "this",
                    cond: {
                        $eq: [ "$$this.v.name", "Y" ] // we only want the ones where the name is "Y"
                    }
                }
            }
        }
    }
})
Sign up to request clarification or add additional context in comments.

4 Comments

Seems very complex... what is the "v" doing in "$$this.v.name" ?
It's actually not really complex and the default (and only) approach to solving a case like yours. With the aggregation framework you can always just reduce the stages one by one starting from the end to see what's going on. So just remove the second stage and you'll see what's going on. Also, I will simplify the above because it can be written in one single stage, I think.
It seems you know about mongodb. Will it be a bad approach to use the json in json in stead of an array?
I would certainly say you should consider changing your document structure. It's painful to deal with data in this layout. Also on the client side. Things that represent a list of documents should generally be stored as a list (=array), too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.