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字段值的文档。您可以将此阶段作为聚合的第一阶段放置在管道中。哦,很好,我现在明白了!谢谢