【问题标题】:Projection of arrays using $ vs using $slice使用 $ 与使用 $slice 的数组投影
【发布时间】:2014-03-10 14:14:27
【问题描述】:

我的收藏如下:-

{ "_id" : 1, "grades" : [ 70, 87, 90 ] }
{ "_id" : 2, "grades" : [ 90, 88, 92 ] }

我正在使用以下查询:-

db.students.find( { semester: 1, grades: { $gte: 85 } },
                  { "grades.$": 1 } )

我得到的结果是:-

{ "_id" : 1, "grades" : [ 87 ] }
{ "_id" : 2, "grades" : [ 90 ] }

现在我的问题是,当我在字段等级上使用 $gte 时,它​​将检查数组的任何元素是否匹配条件,如果匹配则返回文档。那么为什么我的第一个文档的输出是 87 而不是 70。我知道我们已经指定了一个相等条件“grades: { $gte: 85 }”,但它返回了完整的文档并投影了第一个字段。那为什么输出是87呢?

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    那么为什么我的第一个文档的输出是 87 而不是 70。

    因为您特别要求它。这正是 positional projection operator $ 的用途:它返回与查询匹配的 first 元素,因此投影 grades.$ : 1 将返回一个数组,其中包含数组中的第一个也是唯一一个元素符合条件的,即第一个元素大于等于85。

    它仍然是一个数组可能会让人恼火——毕竟,因为它总是只有一个元素,它们可以只为您提供像grades:87 这样的值。不过,这是 MongoDB 中的一种模式:除非您使用聚合框架,否则它不会修改数据结构,从而更容易将查询结果映射到静态类型语言。

    如果您想使用整个数组,则根本不需要投影:

    db.students.find( { semester: 1, grades: { $gte: 85 } } )
    { "_id" : 1, semester: 1, "grades" : [  70,  87,  90 ] }
    { "_id" : 2, semester: 1, "grades" : [  90,  88,  92 ] }
    

    如果你只想要数组中的第一个元素(不是第一个 匹配 元素),你可以使用$slice:

    db.students.find({semester: 1, grades: { $gte: 85 } },{ "grades": {$slice : 1}});
    { "_id" : 1, semester: 1, "grades" : [  70 ] }
    { "_id" : 2, semester: 1, "grades" : [  90 ] }
    

    【讨论】:

    • 我有一个疑问,我的想法是,当我们用投影查询任何东西时,会发生两件事。 1)一个游标返回满足条件的文档,所以在这种情况下它是 {“_id”:1,学期:1,“等级”:[70,87,90]} {“_id”:2,学期:1,“等级”:[90,88,92]}。 2)现在投影适用,我们得到第一个元素是 {“_id”:1,学期:1,“成绩”:[70]} {“_id”:2,学期:1,“成绩”:[90 ] } 那么为什么 87 排在第一位呢? $有什么智慧吗??
    • 投影是游标的一部分,它不是在游标返回结果后发生的二次操作,而是在游标迭代期间使用,因此它知道匹配过程,是的,否则它无法完成它的工作。
    猜你喜欢
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 2017-07-03
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多