簡體   English   中英

MongoDB-不同,限制和排序以獲得更好的結果

[英]MongoDB - Distinct, Limit, and Sort for better results

我正在嘗試開發一個查詢,以幫助在MongoDB中的搜索請求中混合結果。 我的收藏的一個示例(非常簡化的版本)如下所示。 每個文檔都有要查詢的位置,清單質量的等級以及插入清單的提供者的名稱。

[
  {
    "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個。因此,即使Alphas仍然排名靠前,它們也將被限制為3個,以使Beta和Omega更高。 然后,當使用.skip時,可以在“第2頁”上看到其余的Alpha。

如果我要在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萬份文檔。 我怎么能在蒙哥斯方面做到這一點? 謝謝!

您可以嘗試一些服務器端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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM