Python MongoDB-区分、限制和排序以获得更好的结果
我正在尝试开发一个查询,以帮助在MongoDB中混合搜索请求中的结果。我的收藏的一个示例(非常简化的版本)如下所示。每个文档都有一个要查询的位置、列表质量的排名以及插入列表的提供者的名称Python MongoDB-区分、限制和排序以获得更好的结果,python,mongodb,pymongo,Python,Mongodb,Pymongo,我正在尝试开发一个查询,以帮助在MongoDB中混合搜索请求中的结果。我的收藏的一个示例(非常简化的版本)如下所示。每个文档都有一个要查询的位置、列表质量的排名以及插入列表的提供者的名称 [ { "location": "paris", "ranking": "998", "provider": "Alpha" }, { "location": "paris", "ranking": "965", "provider": "Alpha"
[
{
"location": "paris",
"ranking": "998",
"provider": "Alpha"
},
{
"location": "paris",
"ranking": "965",
"provider": "Alpha"
},
{
"location": "paris",
"ranking": "945",
"provider": "Alpha"
},
{
"location": "paris",
"ranking": "933",
"provider": "Alpha"
},
{
"location": "paris",
"ranking": "953",
"provider": "Alpha"
},
{
"location": "paris",
"ranking": "983",
"provider": "Alpha"
},
{
"location": "paris",
"ranking": "700",
"provider": "Beta"
},
{
"location": "paris",
"ranking": "745",
"provider": "Beta"
},
{
"location": "paris",
"ranking": "670",
"provider": "Omega"
},
{
"location": "paris",
"ranking": "885",
"provider": "Omega"
},
{
"location": "paris",
"ranking": "500",
"provider": "Omega"
},
{
"location": "london",
"ranking": "600",
"provider": "Omega"
},
{
"location": "london",
"ranking": "650",
"provider": "Beta"
}
]
正如您所见,提供商Alpha拥有最多的列表和最好的排名。因此,当我搜索巴黎并按排名排序时,所有来自Alpha提供商的列表都会排在首位,而Beta和Omega则排在了底部
我想做的是将每个提供者限制为3个。因此,即使阿尔法仍然在顶部,他们将被限制在3允许贝塔和欧米茄更高。当使用.skip时,剩下的字母可以在“第2页”上看到
如果我在Python中这样做,那么同步示例将如下所示
#!/usr/bin/env python
# -*- coding: utf-8 -*-
results = []
providersAvailable = colc.find({'location': 'paris'}).distinct('provider')
for provider in providersAvailable:
search = colc.find({'provider':provider, 'location': 'paris'}).limit(3)
results = results + list(search)
return sorted(results, key=lambda k: k['ranking'])
这是一项繁重、耗时的工作,而且总体来说非常糟糕,尤其是收集了250万份文档。我怎么能在Mongos这边做到这一切?谢谢 你可以试试服务器端的JS
var providers = db.runCommand({distinct:"colc", key:"provider"}).values
for(p in providers){
var c = db.colc.find({"provider":providers[p]}).sort({"ranking":-1}).limit(3);
c.forEach(printjson);
}
但是,由于所有的JS都被解释,它不会是最快的选择
您可以使用聚合框架,它主要是服务器端的热门产品,例如
db.colc.aggregate([
{$match: {"location":"paris"}},
{$group:{_id: { "provider": "$provider", "location":"$location"},
"rankings" : { $addToSet: "$ranking"} } }
]);
但是,您需要一些客户端代码来从返回数组中选择每个提供者的排名
{
"result" : [
{
"_id" : {
"provider" : "Omega",
"location" : "paris"
},
"rankings" : [
"500",
"885",
"670"
]
},
{
"_id" : {
"provider" : "Beta",
"location" : "paris"
},
"rankings" : [
"745",
"700"
]
},
{
"_id" : {
"provider" : "Alpha",
"location" : "paris"
},
"rankings" : [
"983",
"953",
"933",
"945",
"965",
"998"
]
}
],
"ok" : 1
}
你看过聚合框架了吗?你的索引呢?我已经看过了聚合框架,但是还没有把一些有意义的东西放在一起。目前,我只是有一个复合索引,它的位置比我为当前示例创建的提供程序要高。如果有更好的选择,当然愿意更改。如果您使用
提供者在位置
上建立索引,代码中的distinct将被快速索引。我看不出还有什么比这更重或更慢的了。