【问题标题】:Is it possible to get the fields in the order of projection in Aggregation Frameworks mongo是否可以在聚合框架 mongo 中按投影顺序获取字段
【发布时间】:2016-05-17 04:47:41
【问题描述】:

我有以下文件:

{ "_id" : 3, "quizzes" : [ 4, 5, 5 ], "labs" : [ 6, 5 ], "final" : 78, "midterm" : 70 }
{ "_id" : 1, "quizzes" : [ 4, 5, 5 ], "labs" : [ 6, 5 ], "midterm" : 70 }

如果我运行以下查询:

   db.students.aggregate([  { "$project": {  "midterm": 1,"final": 1   } } ])

结果如下:

{ "_id" : 3, "final" : 78, "midterm" : 70 }
{ "_id" : 1, "midterm" : 70 }

如果我仍然在 shell 中更改投影顺序,字段的顺序是否相同?我们可以保留其查询的顺序吗?

db.students.aggregate([  { "$project": { "final":1, "midterm": 1  } } ])
{ "_id" : 3, "final" : 78, "midterm" : 70 }
{ "_id" : 1, "midterm" : 70 }

顺序很重要的用例:

我有一个集合,它为用户存储每日明智的数据。如果用户在那天做了一些活动,那么文档中会有一个字段用于该用户。我们将这一天存储 200 天......在另一个集合中我们必须更新过去 200 天内 userFirstActive 的时间...

注意:在用户没有执行任何活动的那一天,该键不会有任何条目...

因此,如果我们进行 200 天的预测……除了 id 之外的第一个条目将是第一个活动日……是否可以在不获取整个文档并检查密钥是否存在的情况下实现这一目标?

【问题讨论】:

  • 简短回答否!但是您可以使用$sort 运算符指定顺序。
  • @user3100115 实际上不是OP所要求的,而是“字段”的顺序而不是文档的顺序。有很多方法可以做到这一点,以及为什么“字段”并不总是按照您要求的顺序出现的原因。

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

在聚合数组的最后一个值中,添加这个属性

  {
    $replaceRoot: {
      newRoot: {
        field_1: '$field_1',
        field_2: '$field_2',
        ...
      }
    }
  }

【讨论】:

    【解决方案2】:

    默认情况下,MongoDB 按插入顺序返回字段。

    例如

    db.students.aggregate([  { "$project": {  "midterm": 1,"final": 1   } } ])
    

    将返回

    { "_id" : 3, "final" : 78, "midterm" : 70 }
    { "_id" : 2, "midterm" : 60, "final" : 55 }
    { "_id" : 1, "midterm" : 70 }
    

    你可以看到第二条记录,它的字段是我们插入的顺序。 但是,我们可以通过重命名字段来玩一个技巧,让它们按您想要的顺序排列。

    例如

    db.students.aggregate([  { "$project": {  _midterm:"$midterm","_final": "$final"}}])
    

    上面的查询将返回

    { "_id" : 3, "_midterm" : 70, "_final" : 78 }
    { "_id" : 2, "_midterm" : 60, "_final" : 55 }
    { "_id" : 1, "_midterm" : 70 }
    

    这里的期中考试排在第一位,期末考试排在第二位,但有一个例外。字段名称以_ 为前缀。如果你想要原名,你可以再次project

    db.students.aggregate(
    [
    { "$project": {  _midterm:"$midterm","_final": "$final"}},
    { "$project": {  midterm:"$_midterm","final": "$_final"}}
    ])
    

    它会返回

    { "_id" : 3, "midterm" : 70, "final" : 78 }
    { "_id" : 2, "midterm" : 60, "final" : 55 }
    { "_id" : 1, "midterm" : 70 }
    

    【讨论】:

    • 真正的原因并不是“插入顺序”,而是字段在前一个管道阶段的顺序,因为像$project$group这样的操作实际上是“复制”位置和/或内容作为“优化”技术。所以你是正确的,确保不同排序的唯一方法是使用“临时”名称或有效的不同名称。就在这种情况下,提案并不是最有效的做法。
    • @Blakes 七,你是对的。字段顺序确实取决于先前的管道阶段。但是我指的是文档中字段的顺序(在没有聚合阶段)。实际上,我插入了具有随机字段顺序的文档,当检索回来时,原始字段顺序保持不变。这个判断是我说“插入顺序”时的基础,可能是用词错误。
    • 这是一个巧妙的解决方法。我不知道你可以重新投影一个投影。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-05-04
    • 2023-03-31
    • 2017-09-18
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    相关资源
    最近更新 更多