Mongodb 如何获取投影的所有文档或仅获取一个文档?
我的文档如下所示:Mongodb 如何获取投影的所有文档或仅获取一个文档?,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我的文档如下所示: { "_id": xxxx, "user_id1": "1234", "user_id2": "2345", "amount": 30000, "code": "ABC1", "date_processed": datetime.datetime(2020, 5, 11), ... } 如果它们有相同的代码字段,我将对给定时间段的金额进行汇总。下面是它的样子: cursor = db.aggregate([ {
{
"_id": xxxx,
"user_id1": "1234",
"user_id2": "2345",
"amount": 30000,
"code": "ABC1",
"date_processed": datetime.datetime(2020, 5, 11),
...
}
如果它们有相同的代码字段,我将对给定时间段的金额进行汇总。下面是它的样子:
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可以是相同的值,在这种情况下,我想过滤掉除第一次出现之外的所有值。这可能吗?我已经查看了聚合文档中的每一个操作,但似乎没有一个简单的管道来实现这一点。我当前的路径是尝试:
{"$match": {"$user_id1": 1234, "code": "ABC1"}},
{"$group": {"_id": "$user_id2", "matches": {"$push": {"$eq": ["user_id1", "user_id2"]}}}},
...
这看起来很有希望,因为我现在得到了一个布尔值列表,当ID匹配时,所有的布尔值都是真的,当ID不匹配时,所有的布尔值都是假的。然后,我可以在投影中使用$arrayElemAt查看这些元素,但我不确定如何在为False时扩展到整个数组,或者在为True时仅扩展到第一个元素
如果这还不够清楚,那么进行筛选的原因是,当user_id1和user_id2相同时,文档是重复的,它们在数据库中是这样设计的,我希望避免对这些特定的重复文档求和。提前谢谢
我的问题是:有时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"
}
美好的然而,这看起来好像也取代了user_id1和user_id2不同的文档,我希望这些文档保持不变。也许我可以根据ID是否相同进行切换。我只是添加了一些示例文档——在我发布的聚合阶段之前和之后。如果您只想处理带有条件的某些文档,可以使用$match阶段进行筛选。例如,stage{$match:{$expr:{$eq:[$user_id1,$user_id2]}}}将只筛选具有相同user_id1和user_id2字段值的文档。您可以将此阶段作为聚合的第一阶段放置在管道中。哦,很好,我现在明白了!谢谢