问题
I have a collection with entries that look like :
{
"userid": 1,
"contents": [
{ "tag": "whatever", "value": 100 },
{"tag": "whatever2", "value": 110 }
]
}
I'd like to be able to query on that collection and returning only one part of the array : the one matching the query. I'm trying to use the $ positional operator to do so but it hasn't worked so far.
Here is more precisely what I'd like to do :
collection.find({'contents.tag':"whatever"},{'contents.$.value':1})
As a result I expect sth with only the value corresponding to the entry in the array that matched query, which is 100 in this case.
Do you know what's wrong ? I was thinking that maybe the $ operator can only be used for update and not for querying. Anyone in the know ?
Thanks !
回答1:
Yes, you are correct - the positional operator is used for updating an object.
The solution for now would be to return the array an pull the field out in your application.
There is an open enhancement request for this feature (in queries):
https://jira.mongodb.org/browse/SERVER-828
For more information on the positional operator, see:
http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator
回答2:
What you are looking for is the $elemMatch operator.
回答3:
It might be an overkill, but I guess you can use map-reduce for this.
first, pre-filter with a query, emit all array elements in map, filter the ones that do not match either in emit or in reduce. If you don't set out everything will happen in RAM.
If you have to run those kinds of queries often, it might be worthwhile to duplicate the data.
Nevertheless, I hope the SERVER-828 will be implemented soon!
回答4:
Create a query with $in instead and add your equal value to the array, this can solve your issue
$users_array = array(xxxxxxxx,yyyyyy);
$user = Db::find('fb_users', array(
'facebook_id' => array(
'$in' => array($users_array)
)
));
来源:https://stackoverflow.com/questions/6280259/mongodb-use-positional-operator-for-querying