Mongo Join String Array

时间:2013-02-16 21:16:59

标签: node.js mongodb

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

文件:

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

期望的输出:

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

3 个答案:

答案 0 :(得分:1)

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

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 ] 使子字符串从索引 1 开始,长度为 -1,在这种情况下是“尽可能多”。

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

答案 1 :(得分:1)

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

{
"$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: ","
            }
          }
        ]
      }
    }
  }
}

}

答案 2 :(得分: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" } }