MongoDB Aggregation join array of strings to single string

戏子无情 提交于 2020-08-22 04:07:32

问题


We're trying to 'join' an array of strings to a single string within an aggregation.

Given is the following dataset:

Collection 1:

{
  id: 1234,
  field: 'test'
}

Collection 2:

{
  id: 1111,
  collection1_id: 1234,
  name: 'Max'
},
{
  id: 1112,
  collection1_id: 1234,
  name: 'Andy'
}

The current result (after lookup etc.):

{
  id: 1234,
  field: 'test',
  collection2: ['Max', 'Andy'] 
}

The desired result:

{
  id: 1234,
  field: 'test',
  collection2: 'Max, Andy'
}

Is it somehow possible to join the 'collection2' to a single string? We've tried with $concat but it only accepts strings.


回答1:


You were on the right track.

Just add $reduce over $concat in your $project stage.

'collection2': {
    '$reduce': {
        'input': '$collection2',
        'initialValue': '',
        'in': {
            '$concat': [
                '$$value',
                {'$cond': [{'$eq': ['$$value', '']}, '', ', ']}, 
                '$$this']
        }
    }
}

Note: We use $cond to prevent a leading , in the concatenation. You could also use $substrCP before $reduce as an alternative to $cond.




回答2:


To flatten this array, you need to shift process to client.

mongo will provide some new flattening options in new edition, but afaik it will be arithmetic ones (avg, min, max....).




回答3:


Starting Mongo 4.4, the $group stage has a new aggregation operator $accumulator allowing custom accumulations of documents as they get grouped:

// { "collectionId" : 1234, "name" : "Max"  }
// { "collectionId" : 876,  "name" : "Rob"  }
// { "collectionId" : 1234, "name" : "Andy" }
db.collection.aggregate([
  { $group: {
    _id: "$collectionId",
    names: {
      $accumulator: {
        accumulateArgs: ["$name"],
        init: function() { return [] },
        accumulate: function(names, name) { return names.concat(name) },
        merge: function(names1, names2) { return names1.concat(names2) },
        finalize: function(names) { return names.join(",") },
        lang: "js"
      }
    }
  }}
])
// { "_id" : 876,  "names" : "Rob"      }
// { "_id" : 1234, "names" : "Max,Andy" }

The accumulator:

  • accumulates on the field name (accumulateArgs)
  • is initialised to an empty array (init)
  • accumulates by concatenating new names to already seen names (accumulate and merge)
  • and finally joins all names as a string (finalize)


来源:https://stackoverflow.com/questions/38377582/mongodb-aggregation-join-array-of-strings-to-single-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!