【问题标题】:Specify Multiple Criteria for Array Elements为数组元素指定多个条件
【发布时间】:2016-06-05 20:13:44
【问题描述】:

我正在阅读 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

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    要了解文档所说的内容,您首先需要了解使用数组进行范围查询的工作原理。

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

    { "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 大于20 并且3 小于15。这是因为27 匹配第一个条件,3 匹配第二个条件。这种行为是documentation 中提到的。

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

    结论:

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

    课程:

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

    【讨论】:

    • 我了解您的第一个查询,但想知道范围匹配如何在数组上发生。检查以粗体显示的已编辑问题。如果我们将数组作为 [1,2,3]、[21,22,23] 和 [16,999,999] 用于第二个查询呢?
    • @BangOperator 如果您的数组看起来像这样,则只会返回 [16, 999, 999],因为 15<16<20 我已经更新了答案
    【解决方案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 } } } )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-04
      • 2020-11-26
      • 2016-10-27
      • 1970-01-01
      • 2018-05-02
      • 1970-01-01
      • 2020-03-19
      相关资源
      最近更新 更多