我有像这样结构的MongoDB文档:
{_id: ObjectId("53d760721423030c7e14266f"), fruit: 'apple', vitamins: [ { _id: 1, name: 'B7', usefulness: 'useful', state: 'free', } { _id: 2, name: 'A1', usefulness: 'useful', state: 'free', } { _id: 3, name: 'A1', usefulness: 'useful', state: 'non_free', } ] } {_id: ObjectId("53d760721423030c7e142670"), fruit: 'grape', vitamins: [ { _id: 4, name: 'B6', usefulness: 'useful', state: 'free', } { _id: 5, name: 'A1', usefulness: 'useful', state: 'non_free', } { _id: 6, name: 'Q5', usefulness: 'non_useful', state: 'non_free', } ] }
我想查询并获得具有{name: 'A1', state: 'non_free'}
和的所有水果{name: 'B7', state: 'free'}
.在最坏的情况下,我想至少要计算这些条目,如果不可能获得它们,并且如果pymongo存在等效代码,则知道如何编写它.
对于给定的示例,我想只检索apple(第一个)文档.
如果我使用$elemMatch
它只适用于一种情况,但不适用于两种情况.例如,如果我查询find({'vitamins': {'$elemMatch': {'name': 'A1', 'state': 'non_free'}, '$elemMatch': {'name': 'B7', 'state': 'free'}}})
它将检索所有的水果{'name': 'B7', 'state': 'free'}
.
在这种情况下,您可以使用$and
-operator.
试试这个查询:
find({ $and: [ {'vitamins': {'$elemMatch': {'name': 'A1', 'state': 'non_free'} } }, {'vitamins': {'$elemMatch': {'name': 'B7', 'state': 'free'} } } ] });
解释为什么只收到与第二个条件匹配的结果:{}
传递给MongoDB的每个对象都是键/值对.每个键每个对象只能存在一次.当您尝试将值分配给同一个键两次时,第二个赋值将覆盖第一个.在您的情况下,您$elemMatch
为同一对象中的键分配了两个不同的值,因此忽略了第一个值.实际到达MongoDB的查询只是find({'vitamins': {'$elemMatch': {'name': 'B7', 'state': 'free'}}})
.
每当您需要将同一个操作符应用于同一个键两次时,您需要使用$or
或$and
.