What I have :
{ "_id" : ObjectId("577dc9d61a0b7e0a40499f90"), "equ" : 123456, "key" : "p" }
{ "_id" : ObjectId("577c789b1a0b7e0a403f1b52"), "equ" : 123456, "key" : "r" }
{ "_id" : ObjectId("577b27481a0b7e0a4033965a"), "equ" : 123456, "key" : "r" }
{ "_id" : ObjectId("5779d6111a0b7e0a40282dc7"), "equ" : 123456, "key" : "o" }
What I want :
{ "_id" : ObjectId("5779d6111a0b7e0a40282dc7"), "equ" : 123456, "keys" : "prro" }
What I tried :
db.table.aggregate([{"$group":{"_id":0, "keys":{"$push":"$key"}}}])
returns an array and not a string:
{"_id":0, "keys":["p","r","r","o"]}
Do you have any idea?
Concatenates strings and returns the concatenated string. $concat has the following syntax: { $concat: [ <expression1>, <expression2>, ... ] } The arguments can be any valid expression as long as they resolve to strings.
If the value is an array, $push appends the whole array as a single element. To add each element of the value separately, use the $each modifier with $push . For an example, see Append a Value to Arrays in Multiple Documents. For a list of modifiers available for $push , see Modifiers.
The pipeline provides efficient data aggregation using native operations within MongoDB, and is the preferred method for data aggregation in MongoDB. The aggregation pipeline can operate on a sharded collection.
The MongoDB aggregation framework is an extremely powerful set of tools. The processing is done on the server itself which results in less data being sent over the network.
Use this aggregation pipeline:
db.col.aggregate([
{$group: {_id: "$equ", last: {$last: "$_id"}, keys: {$push: "$key"}}},
{
$project: {
equ: "$_id",
_id: "$last",
keys: {
$reduce: {
input: "$keys",
initialValue: "",
in: {$concat: ["$$value", "$$this"]}
}
}
}
}
])
First you should group the documents based on the equ
value and also maintain an array of keys along with the _id
of the last group member:
var groupByEqu = {
$group: {
_id: "$equ",
last: {$last: "$_id"},
keys: {$push: "$key"}
}
}
Just applying this pipeline operation would result in:
{
"_id" : 123456,
"last" : ObjectId("5779d6111a0b7e0a40282dc7"),
"keys" : [ "p", "r", "r", "o" ]
}
You should use a Projection to transform the preceding document into your desired one. The first two transformations are trivial. For joining the array elements you can use the new $reduce
operator:
var project = {
$project: {
equ: "$_id",
_id: "$last",
keys: {
$reduce: {
input: "$keys",
initialValue: "",
in: {$concat: ["$$value", "$$this"]}
}
}
}
}
Applying these two pipeline operations would give you the desired result:
db.col.aggregate([groupByEqu, project])
Which is:
{
"equ" : 123456,
"_id" : ObjectId("5779d6111a0b7e0a40282dc7"),
"keys" : "prro"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With