简体   繁体   中英

Mongodb: Querying array of subdocuments

I have users' collection whose schema is like:

{
  _id: unique number,
  name: 'asdf',
  age: '12',
  gender: 'm',
  address: [
    {area: 'sdf',
     city: 'sdq', 
     state: 'wfw'},
    {area: 'asdf',
     city: 'sdfs',
     state: 'vfdwd'}
  ]
}

I want to find out the users for whom all the values of state in address should be the value I pass. If even one of the state value doesn't match with the value I pass the user shouldn't be returned. I tried simple find, aggregation framework with $unwind , $match but nothing seemed to get solution. Can you please help me out...

Thanks

PS please bear with multiple addresses for the sake of question. :)

To find out if all array entries match the state "wfw", do an aggregation like the following:

db.users.aggregate([
    { "$project" : {
        "test" : {
            "$allElementsTrue" : [{
                "$map" : { 
                    "input" : "$address", 
                    "as" : "a", 
                    "in" : { "$eq" : ["wfw", "$$a.state"] }
                }
            }]
        }
    } },
    { "$match" : { "test" : true } }
])

This aggregation takes each document, maps "state equals 'wfw'" over the address array to get a boolean array, and tests if the entire array is true, storing the result in `test, and then filtering the results based on test. You will need MongoDB 2.6 for support of some of the operators.

I don't know if I understand.

I replicated your document. When you want to retrieve an user by state you can do in many ways

If you search with single value you can do

db.g.find({ "address.state": "wfw" })

and retrieve an user

You can use $all

db.g.find( { "address.state": { $all: ["wfw","vfdwd"] } } ) // retrieve User

db.g.find( { "address.state": { $all: ["wfw","vfdwd","foo"] } } ) // don't retrieve User

or you can use $and

db.g.find( { $and: [ { "address.state":"wfw" },{ "address.state":"vfdwd" }] } )

But I don't know if I understand your question

Update and the correct answer

db.g.find( { "address.state": { $nin: ["wfw"] } } )

Let me Know

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM