如何过滤对象数组以根据 MongoDB 聚合中的条件删除元素?
How to filter an array of objects to remove elements based on condition in MongoDB aggregate?
我在 MongoDB 中有一组文档 ChatRooms
具有以下(简化)结构:
{
_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')
},
]
}
我想要实现的是过滤 aggregate
管道内的 messages
数组,以获得 userId
只存在一次的数组。我正在寻找的结果是(或类似的东西,但数组不应该有两个具有相同 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')
},
]
}
这种事情有可能吗?
任何帮助将不胜感激。
您可以通过几种不同的方式做到这一点,这里是一个如何使用 $reduce
运算符实现这一点的示例:
db.collection.aggregate([
{
$addFields: {
messages: {
$reduce: {
input: "$messages",
initialValue: [],
in: {
$cond: [
{
$in: [
"$$this.user",
"$$value.user"
]
},
"$$value",
{
"$concatArrays": [
"$$value",
[
"$$this"
]
]
}
]
}
}
}
}
}
])
我在 MongoDB 中有一组文档 ChatRooms
具有以下(简化)结构:
{
_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')
},
]
}
我想要实现的是过滤 aggregate
管道内的 messages
数组,以获得 userId
只存在一次的数组。我正在寻找的结果是(或类似的东西,但数组不应该有两个具有相同 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')
},
]
}
这种事情有可能吗? 任何帮助将不胜感激。
您可以通过几种不同的方式做到这一点,这里是一个如何使用 $reduce
运算符实现这一点的示例:
db.collection.aggregate([
{
$addFields: {
messages: {
$reduce: {
input: "$messages",
initialValue: [],
in: {
$cond: [
{
$in: [
"$$this.user",
"$$value.user"
]
},
"$$value",
{
"$concatArrays": [
"$$value",
[
"$$this"
]
]
}
]
}
}
}
}
}
])