MongoDB:如何在聚合上应用多个 $project

标签 mongodb mongodb-query aggregation-framework

下面给出的是来自 my_collection 的示例文档

{
  "_id":ObjectId("5b3f4e1013aad111501b34c4")
  "Text":["kjsdf sdfjgnks vk ekl sdsdd."],
  "Title":["lkdjf wufk"],
  "List":["3412","1244","7654","8476"],
  "__v":0
}

我想聚合 my_collection 使得:
  • 生成一个字段“totalList”,它包含字段“List”中数组中的项目数。
  • 防止字段“__v”出现在结果中。
  • 将输出字段“列表”的值更改为数组
  • 的连接
  • 删除“列表”中字符串末尾的尾随逗号
  • 将第 4 点生成的字符串截短,只包含“列表”字段的前 50 个字符

  • 所以我写了这段代码:
      db.my_collection.aggregate( 
          [ 
             {
               $addFields: {
                 totalList: { $size: "$List" }  // I can achieve the 1st point with this
               }
             },
             { $project : { 
                              __v:0,  // I can achieve the 2nd point with this
                              List:
                              {
                                $reduce:  // I can achieve the 3rd point with this
                                   {
                                     input: "$List",
                                     initialValue: "",
                                     in: { $concat : ["$$value", "$$this", ","] }
                                   }
                              }
                           }
              }
          ] 
      );
    

    但是,当我运行上述命令时出现以下错误:
      Failed to execute a script.
    
      Error:
      Assert: command failed: {
        "ok" : 0,
        "errmsg" : "Bad projection specification, cannot include fields or add computed fields during an exclusion projection: { __v: 0.0, List: { $reduce: { input: \"$List\", initialValue: \"\", in: { $concat: [ \"$$value\", \"$$this\", \",\" ] } } } }",
        "code" : 40182,
        "codeName" : "Location40182"
      } : aggregate failed
      _getErrorWithCode@src/mongo/shell/utils.js:25:13
      doassert@src/mongo/shell/assert.js:16:14
      assert.commandWorked@src/mongo/shell/assert.js:370:5
      DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1319:5
      DBCollection.prototype.aggregate@:1:355
      @(shell):1:1
    
      Error: command failed: {
        "ok" : 0,
        "errmsg" : "Bad projection specification, cannot include fields or add computed fields during an exclusion projection: { __v: 0.0, List: { $reduce: { input: \"$List\", initialValue: \"\", in: { $concat: [ \"$$value\", \"$$this\", \",\" ] } } } }",
        "code" : 40182,
        "codeName" : "Location40182"
      } : aggregate failed :
      _getErrorWithCode@src/mongo/shell/utils.js:25:13
      doassert@src/mongo/shell/assert.js:16:14
      assert.commandWorked@src/mongo/shell/assert.js:370:5
      DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1319:5
      DBCollection.prototype.aggregate@:1:355
      @(shell):1:1
    

    因此,我将其改写为:
      db.my_collection.aggregate( 
          [ 
             {
               $addFields: {
                 totalList: { $size: "$List" }  // Achieve the 1st point with this
               }
             },
             { $project : { 
                              "Text":1,
                              "Title":1,
                              __v:{     // Achieve the 2nd point with this
                                  $cond: {
                                     if: { $eq: [1,1] },
                                     then: "$$REMOVE",
                                     else: 0
                                  }
                              },
                              List:
                              {
                                $reduce:  // Achieve the 3rd point with this
                                   {
                                     input: "$List",
                                     initialValue: "",
                                     in: { $concat : ["$$value", "$$this", ","] }
                                   }
                              }
                           }
              }
          ] 
      );
    

    现在,我可以达到前 3 分。
    但是,我怎样才能达到第 4 点和第 5 点?

    最佳答案

    您可以尝试以下聚合

    db.collection.aggregate([
      { "$addFields": {
        "totalList": { "$size": "$List" },
        "List": {
          "$substr": [
            { "$reduce": {
              "input": "$List",
              "initialValue": "",
              "in": { "$concat": ["$$value", ",", "$$this"] }
            }},
            1,
            50
          ]
        }
      }},
      { "$project": { "List": 1, "Test": 1, "Title": 1, "totalList": 1 }}
    ])
    

    输出
    [
      {
        "List": "3412,1244,7654,8476",
        "Title": [
          "lkdjf wufk"
        ],
        "_id": ObjectId("5b3f4e1013aad111501b34c4"),
        "totalList": 4
      }
    ]
    

    试试看 here

    关于MongoDB:如何在聚合上应用多个 $project,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51319958/

    相关文章:

    mongodb - 汇总返回特定字段

    mongodb - 在嵌套数组中查找第一个符合条件的元素

    mysql - Mongo - MySql 之间喜欢

    mongodb - 将 $Redact 与正则表达式一起使用

    node.js - 在没有 $unwind 的情况下查找数组内的重复项

    mongodb - 没有索引的MongoDB搜索真的很慢吗?

    mongodb - 从 Grails 应用程序更新 Mongo 文档字段

    mongodb - MongoDB 的 'lost data' 批评在多大程度上仍然有效?

    database - Elastic Search 作为持久数据库

    javascript - Mongodb 聚合以对数组中最常见的项目进行排序?