I have a collection of documents ChatRooms
in MongoDB that has this (simplified) structure:
{
_id: ObjectId('4654'),
messages: [
{
user: ObjectId('1234'),
sentAt: ISODate('2022-03-01T00:00:00.000Z')
},
{
user: ObjectId('1234'),
sentAt: ISODate('2022-03-02T00:00:00.000Z')
},
{
user: ObjectId('8888'),
sentAt: ISODate('2022-03-03T00:00:00.000Z')
},
]
}
What I'm trying to achieve is to filter the messages
array inside the aggregate
pipeline in order to get an array where the userId
is presend just once. The result I'm looking for is (or something similar but the array shouldn't have two elements with the same user
id):
{
_id: ObjectId('4654'),
messages: [
{
user: ObjectId('1234'),
sentAt: ISODate('2022-03-01T00:00:00.000Z')
},
{
user: ObjectId('8888'),
sentAt: ISODate('2022-03-03T00:00:00.000Z')
},
]
}
Is such a thing possible even? Any help would be much appreciated.
CodePudding user response:
You can do this in several different ways, here is an example of how to achieve this using the $reduce
operator:
db.collection.aggregate([
{
$addFields: {
messages: {
$reduce: {
input: "$messages",
initialValue: [],
in: {
$cond: [
{
$in: [
"$$this.user",
"$$value.user"
]
},
"$$value",
{
"$concatArrays": [
"$$value",
[
"$$this"
]
]
}
]
}
}
}
}
}
])