为数组元素指定多个条件

时间:2016-06-05 20:13:44

标签: mongodb mongodb-query

我正在阅读mongodb here的文档, 我无法理解这两个命令以及它们之间的不同。

db.users.find( { finished: { $elemMatch: { $gt: 15, $lt: 20 } } } )

我的理解:至少有一个元素需要同时满足这两个条件。

  

元素组合满足标准 ...一个元素可以满足大于15的条件,另一个元素可以满足   小于20的条件,或单个元素可以满足两者

db.users.find( { finished: { $gt: 15, $lt: 20 } } )

问题:阵列上的范围匹配如何发生? 如果一个元素满足$gt:15,这个条件用完了,其他元素检查其余条件,即$lt:20

2 个答案:

答案 0 :(得分:2)

假设我们的集合中有这两个文件:

{
        "_id" : ObjectId("57548c14da05625a928404fd"),
        "finished" : [16, 21]
},
{
        "_id" : ObjectId("57548c1bda05625a928404fe"),
        "finished" : [3, 36]
}

假设您希望完成的数组包含至少一个大于15且小于20的元素的所有文档(显然,第一个文档中只有16符合此条件)。如果您发出:

db.users.find( { finished: { $gt: 15, $lt: 20 } } )

它不会与第一个文档匹配,而是与两个文档匹配。为什么呢?

前面的查询存在的问题是字段引用不限于单个finished元素。因此,只要finished元素中的一个大于15而另一个小于20,此查询将匹配,但您想要的是两个属性应用于相同的已完成元素。 MongoDB文档中的Combination of Elements Satisfies the Criteria部分通过以下方式说明了这一事实:

  

以下示例查询已完成数组的文档   包含某些组合满足查询的元素   条件;例如,一个元素可以满足大于15   条件和另一个元素可以满足小于20的条件,   或单个元素可以满足两者

为了限制匹配过程,您应该使用$elemMatch运算符:

db.users.find( { finished: { $elemMatch: { $gt: 15, $lt: 20 } } } )

答案 1 :(得分:2)

要了解文档的内容,首先需要了解数组范围查询的工作原理。

假设您的收藏中包含以下文档:

{ "finished" : [ 27, 3 ] },
{ "finished" : 17 }

第一个查询:

db.users.find( { "finished": { "$elemMatch": { "$gt": 15, "$lt": 20 } } } )

仅返回“finished”为数组的文档。这是因为$elemMatch运算符仅匹配字段为数组且单个元素满足所有查询条件的文档。

但第二个问题是:

db.users.find( { "finished": { "$gt": 15, "$lt": 20 } } )

将返回两个可能不符合您要求的文档,因为27大于203小于15。这是因为27匹配第一个条件而3匹配第二个条件。这种行为是documentation中提到的。

  

...一个元素可以满足大于15的条件,另一个元素可以满足小于20的条件,或者单个元素可以满足两个条件:

结论:

针对数组的范围查询将匹配数组中符合所有查询条件的一个或多个元素。

课:

不要对数组使用范围查询。你会得到意想不到的结果。