MongoDB、PyMongo - 根据查找条件聚合
MongoDB, PyMongo - aggregate with find conditions
我的数据库中有超过 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} }
])
但是那个pipeline
只给我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
with (type: VIEW_ITEM
or type: BUY_ITEM
) 且createTime最新的文档,你需要进行聚合管道展示有以下演员(阶段):
$match
阶段:
- 这将过滤所有类型为
VIEW_ITEM
或 BUY_ITEM
的文档。您可以在查询中使用 $in
运算符,因为它允许您 select type
字段的值等于任何值的文档指定的数组,它恰好是一个包含两个可能类型值的列表,即 ["VIEW_ITEM", "BUY_ITEM"]
.
$sort
阶段
- 这将提供来自先前管道(上方)的文档的订购。这是必要的,因为您希望在最新的
createTime
字段上聚合这些过滤后的文档。
$group
阶段
- 在最后一步中,您按
oldSessionId
键对所有排序的文档进行分组,使用 $first
运算符添加您想要的字段。
将上述所有管道拼接在一起形成以下聚合管道:
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" },
}
}
]
我的数据库中有超过 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} }
])
但是那个pipeline
只给我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
with (type: VIEW_ITEM
or type: BUY_ITEM
) 且createTime最新的文档,你需要进行聚合管道展示有以下演员(阶段):
$match
阶段:- 这将过滤所有类型为
VIEW_ITEM
或BUY_ITEM
的文档。您可以在查询中使用$in
运算符,因为它允许您 selecttype
字段的值等于任何值的文档指定的数组,它恰好是一个包含两个可能类型值的列表,即["VIEW_ITEM", "BUY_ITEM"]
.
- 这将过滤所有类型为
$sort
阶段- 这将提供来自先前管道(上方)的文档的订购。这是必要的,因为您希望在最新的
createTime
字段上聚合这些过滤后的文档。
- 这将提供来自先前管道(上方)的文档的订购。这是必要的,因为您希望在最新的
$group
阶段- 在最后一步中,您按
oldSessionId
键对所有排序的文档进行分组,使用$first
运算符添加您想要的字段。
- 在最后一步中,您按
将上述所有管道拼接在一起形成以下聚合管道:
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" },
}
}
]