我的文档如下:
{
"_id": xxxx,
"user_id1": "1234",
"user_id2": "2345",
"amount": 30000,
"code": "ABC1",
"date_processed": datetime.datetime(2020, 5, 11),
...
}
,如果它们具有相同的code
字段,则我将汇总给定时间范围内的金额。看起来像这样:
cursor = db.aggregate([
{"$match": {"user_id1": 1234, "code": "ABC1"}},
{"$project": {
"day" {"$cond": [{"$gte": ["$date_processed, datetime.now() - datetime.timedelta(days=1), "$amount", 0]},
"month" {"$cond": [{"$gte": ["$date_processed, datetime.now() - datetime.timedelta(days=30), "$amount", 0]},
"year" {"$cond": [{"$gte": ["$date_processed, datetime.now() - datetime.timedelta(days=365), "$amount", 0]},
}},
{"$group": {
"_id": 1,
"day": {"$sum": "$day"},
"month": {"$sum": "$month"},
"year": {"$sum": "$year"}
}}
])
我的问题是:有时user_id1
和user_id2
可以是相同的值,在这种情况下,我想过滤掉除第一次出现。这可能吗?我已经查看了aggregate()
文档中的所有操作,但似乎并没有一个简单的管道。我当前的路径是尝试:
{"$match": {"$user_id1": 1234, "code": "ABC1"}},
{"$group": {"_id": "$user_id2", "matches": {"$push": {"$eq": ["user_id1", "user_id2"]}}}},
...
这似乎很有希望,因为我现在得到一个布尔值列表,当id匹配时,它们全部为True
,否则为False
。然后,我可以在投影中使用"$arrayElemAt"
来窥视这些内容,但是我不确定如何分支到采用整个数组(当False
时)还是仅采用第一个元素(当True
时) )。
如果这还不够清楚,则进行过滤的原因是,当user_id1
和user_id2
相同时,则文档是重复的(根据设计,它们以这种方式位于db中),我希望避免对这些特定的重复文档进行汇总。预先感谢!
答案 0 :(得分:1)
我的问题是:有时user_id1和user_id2可以是相同的值, 在这种情况下,我想过滤掉除 第一次出现。这可能吗?
聚合的以下两个步骤将删除user_id1
和user_id2
是相同值的重复出现的文档。结果数据集将包含一个没有重复项的文档。
db.collection.aggregate( [
{
$group: {
_id: { user_id1: "$user_id1", user_id2: "$user_id2" },
doc: { $first: "$$ROOT" }
}
},
{
$replaceRoot: { newRoot: "$doc" }
}
] )
对于输入文档:
{
"_id" : ObjectId("5eba05c892367c3459d4e6f4"),
"user_id1" : "1234",
"user_id2" : "2345",
"amount" : 300,
"code" : "ABC1"
}
{
"_id" : ObjectId("5eba05c892367c3459d4e6f5"),
"user_id1" : "1234",
"user_id2" : "6789",
"amount" : 400,
"code" : "DEF1"
}
{
"_id" : ObjectId("5eba05c892367c3459d4e6f6"),
"user_id1" : "999",
"user_id2" : "999",
"amount" : 900,
"code" : "XYZ1"
}
{
"_id" : ObjectId("5eba05c892367c3459d4e6f7"),
"user_id1" : "999",
"user_id2" : "999",
"amount" : 900,
"code" : "XYZ1"
}
输出为:
{
"_id" : ObjectId("5eba05c892367c3459d4e6f6"),
"user_id1" : "999",
"user_id2" : "999",
"amount" : 900,
"code" : "XYZ1"
}
{
"_id" : ObjectId("5eba05c892367c3459d4e6f5"),
"user_id1" : "1234",
"user_id2" : "6789",
"amount" : 400,
"code" : "DEF1"
}
{
"_id" : ObjectId("5eba05c892367c3459d4e6f4"),
"user_id1" : "1234",
"user_id2" : "2345",
"amount" : 300,
"code" : "ABC1"
}