MongoDB、PyMongo - 根据查找条件聚合

标签 mongodb pymongo mongodb-aggregation

我的数据库中有 > 8000 条记录,这是其中之一:

{
    "_id" : ObjectId("57599c498c39598eafb781b9"),
    "_class" : "vn.cdt.entity.db.AccessLog",
    "url" : "/shop/huenguyenshop/browse",
    "ip" : "10.0.0.238",
    "sessionId" : "86E5CF8E6D465A6EDFE7C9BF7890AA4B",
    "oldSessionId" : "86E5CF8E6D465A6EDFE7C9BF7890AA4B",
    "cookie" : "{\"sessionId\":\"86E5CF8E6D465A6EDFE7C9BF7890AA4B\",\"objects\":[{\"id\":\"903815555908\",\"type\":\"VIEW_SHOP\",\"count\":1}]}",
    "isCookie" : true,
    "createTime" : NumberLong(1464935913641),
    "objectId" : "903815555908",
    "type" : "VIEW_SHOP"
}

我想做什么:

我想找到所有具有相同 oldSessionId 的记录(type: VIEW_ITEM or type: BUY_ITEM)并且 createTime最新的

我尝试过的:

pipeline = ([
                {"$group" : { "_id": "$oldSessionId", "count": { "$sum": 1 } }},
                {"$match": {"count" : {"$gt": 1} } },
                {"$project": {"oldSessionId" : "$_id", "_id" : 0} }
            ])

但是那个管道只给我sessionId

    find({'createTime': {'$lt':1464419127000, '$gt':1464332727000}, 
'$or':[{'type':'BUY_ITEM'},{'type':'VIEW_ITEM'}]})

那个find给我在特定时间type:VIEW_ITEMtype:BUY_ITEM的所有记录。

我不知道如何使用 typecreateTime 添加过滤器以获得我想要的。

更新 感谢@chridam 帮助我:

如果我想将特定日期添加到聚合中,我可以像这样进行添加查询:

 pipeline = \
    (
        [
            { "$match": {
                         "createTime": {"$lt":1464419127000, "$gt":1464332727000 },
                         "type": { "$in": ["VIEW_ITEM", "BUY_ITEM"] }
                        }
            },
            { "$sort": { "createTime": -1, "oldSessionId": 1 } },
            {
                "$group":
                    { "_id": "$oldSessionId",
                      "_class": { "$first": "$_class" },
                      "url": { "$first": "$url" },
                      "ip": { "$first": "$ip" },
                      "sessionId": { "$first": "$sessionId" },
                      "oldSessionId": { "$first": "$oldSessionId" },
                      "cookie": { "$first": "$cookie" },
                      "isCookie": { "$first": "$isCookie" },
                      "createTime": { "$first": "$createTime" },
                      "objectId": { "$first": "$objectId" },
                      "type": { "$first": "$type" },
                    }
            }

        ]

    )

最佳答案

要获取具有相同 oldSessionId 的所有文档(类型:VIEW_ITEM 或类型:BUY_ITEM)并且 createTime 是最新的,您需要进行具有以下参与者(阶段)的聚合管道展示:

  1. $match 阶段:

    • 这将过滤所有类型为 VIEW_ITEMBUY_ITEM 的文档。您可以使用 $in 运算符与查询,因为它允许您选择 type 字段的值等于指定数组中的任何值的文档,该数组恰好是具有两个可能类型值的列表即 ["VIEW_ITEM", "BUY_ITEM"]
  2. $sort 阶段

    • 这将提供来自先前管道(上方)的文档的订购。这是必要的,因为您希望在最新的 createTime 字段上聚合这些过滤后的文档。
  3. $group 阶段

    • 在这最后一步中,您按 oldSessionId 键对所有有序文档进行分组,使用 $first 添加您想要的字段 运算符(operator)。

将上述所有管道拼凑在一起形成以下聚合管道:

pipeline = [
    { "$match": {  "type": { "$in": ["VIEW_ITEM", "BUY_ITEM"] } } },
    { "$sort": { "createTime": -1, "oldSessionId": 1 } },
    {
        "$group": {
            "_id": "$oldSessionId",
            "_class": { "$first": "$_class" },
            "url": { "$first": "$url" },
            "ip": { "$first": "$ip" },
            "sessionId": { "$first": "$sessionId" },
            "cookie": { "$first": "$cookie" },
            "isCookie": { "$first": "$isCookie" },
            "createTime": { "$first": "$createTime" },
            "objectId": { "$first": "$objectId" },
            "type": { "$first": "$type" },
        }
    }
]

关于MongoDB、PyMongo - 根据查找条件聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37958808/

相关文章:

json - 使用基于 JSON 的数据库处理无序数据

mongodb - 如何使用golang在mongodb中生成并存储uuid类型0x04?

python - pymongo 在文档中更新/插入字典

python - PyMongo 统计

javascript - Mongoose 对所有文件求和

mongodb - 根据日期范围按日/月/周分组

javascript - 如何查询嵌套文档并从中返回属性?

使用 elemMatch 进行 MongoDB 查询以获取嵌套数组数据

点和美元符号的mongodb含义

node.js - 具有 Mongoose 聚合和求和嵌套字段的 Node