MongoDB,PyMongo - 与查找条件聚合

时间:2016-06-22 04:52:23

标签: 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相同的type: BUY_ITEMcreateTime 最新

我曾尝试过:

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

pipeline只给我sessionId

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

find在特定时间内type: VIEW_ITEM type: 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" },
                    }
            }

        ]

    )

1 个答案:

答案 0 :(得分:1)

要获取具有相同oldSessionId的所有文档(类型:VIEW_ITEM或类型:BUY_ITEM)并且createTime是最新的,您需要执行一个聚合管道显示以下演员(阶段):

  1. $match 阶段:

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

    • 这将提供要订购的上一个管道(上面)的文件。这是必要的,因为您希望在最新的createTime字段上汇总这些已过滤的文档。
  3. $group 阶段

    • 在此最终步骤中,您可以使用oldSessionId键对所有订购的文档进行分组,使用 $first 运算符添加所需的字段。
  4. 将所有上述管道拼接在一起以形成以下聚合管道:

    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" },
            }
        }
    ]