如何获取投影的所有文档或仅获取一个文档?

时间:2020-05-11 23:53:09

标签: mongodb aggregation-framework

我的文档如下:

{
    "_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_id1user_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_id1user_id2相同时,则文档是重复的(根据设计,它们以这种方式位于db中),我希望避免对这些特定的重复文档进行汇总。预先感谢!

1 个答案:

答案 0 :(得分:1)

我的问题是:有时user_id1和user_id2可以是相同的值, 在这种情况下,我想过滤掉除 第一次出现。这可能吗?

聚合的以下两个步骤将删除user_id1user_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"
}