我的数据库中有 > 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_ITEM
或type:BUY_ITEM
的所有记录。
我不知道如何使用 type
和 createTime
添加过滤器以获得我想要的。
更新 感谢@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 是最新的,您需要进行具有以下参与者(阶段)的聚合管道展示:
$match
阶段:- 这将过滤所有类型为
VIEW_ITEM
或BUY_ITEM
的文档。您可以使用$in
运算符与查询,因为它允许您选择type
字段的值等于指定数组中的任何值的文档,该数组恰好是具有两个可能类型值的列表即["VIEW_ITEM", "BUY_ITEM"]
。
- 这将过滤所有类型为
$sort
阶段- 这将提供来自先前管道(上方)的文档的订购。这是必要的,因为您希望在最新的
createTime
字段上聚合这些过滤后的文档。
- 这将提供来自先前管道(上方)的文档的订购。这是必要的,因为您希望在最新的
$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/