1

我正在编写一个应用程序来使用我的 Mongo 数据库中的数据,但我需要以平面格式处理数据。我的文档中有一些数组,我想将它们转换为字符串数组,但找不到使用 mongo 查询的方法。

文档:

{
  name: 'Hello World',
  tags: ['simple', 'easy']
}

期望的输出:

{
  name: 'Hello World',
  tags: 'simple,easy',
}
4

3 回答 3

2

它可以通过以下方式在 MongoDB 聚合中本地完成$reduce

db.myCollection.aggregate([{
  $set: {
     tags: {
       $reduce: {
         input: "$tags",
         initialValue: "",
         in: {
           $concat : ["$$value", "," ,"$$this"]
         }
       }
     }
  }, {
  $project: {
     name: 1,
     tags: { $substr: [ "$tags", 1, -1 ] }
  }
}]);

使用 时无法避免额外的分隔符(前导或尾随)$concat,因此需要额外的步骤$substr来删除它。

  1. $concat : ["$$value", "," ,"$$this"]产生字符串",a,b,c,d"
  2. $substr: [ "$tags", 1, -1 ]使 substring 从 index 开始1, length -1,在这种情况下“尽可能”。

另请参阅$reduce$concat$substr的文档。

于 2021-01-09T06:36:16.973 回答
1

这在一个阶段是非常可行的。addFields 将覆盖 $tags 元素,因为它已经存在。蒙戈游乐场

{
"$addFields": {
  "tags": {
    "$reduce": {
      "input": "$tags",
      "initialValue": "",
      "in": {
        "$concat": [
          //add the running concatination of this array to the front
          "$$value",
          //add the current value after that
          "$$this",
          {
            //comma. if current index is the last element, don't add a comma to the end.
            $cond: {
              if: {
                "$eq": [
                  {
                    $subtract: [
                      {
                        $size: "$tags"
                      },
                      1
                    ]
                  },
                  {
                    $indexOfArray: [
                      "$tags",
                      "$$this"
                    ]
                  }
                ]
              },
              then: "",
              else: ","
            }
          }
        ]
      }
    }
  }
}

}

于 2021-06-28T08:24:31.090 回答
0

我能想到的使用聚合查询实现此目的的唯一方法如下,但它非常静态。

db.test.aggregate([
    { $unwind: "$tags" },
    { $group: { _id: "$_id", name: {$first: "$name"}, firstTag: {$first: "$tags"}, lastTag: {$last: "$tags"} } },
    { $project: { name: "$name", tags: { $concat: [ "$firstTag", ",", "$lastTag" ] } } }
]);

但是,您可以使用 mapReduce 实现此目的:

db.test.mapReduce(
   function() {emit(this._id, this);},
   function(key, value) {return value}, {   
      out:"tags",
      finalize: function(key, reducedVal){
            reducedVal.tags = reducedVal.tags.join();
            return reducedVal;
      }
   }
)

> db.tags.find()
{ "_id" : ObjectId("5849a9f6a4db9c5811299d08"), "value" : { "name" : "Hello World", "tags" : "simple,easy" } }
于 2016-12-08T19:00:44.513 回答