【问题标题】:How to use Distinct, Sort, limit with mongodb如何在 mongodb 中使用 Distinct、Sort、limit
【发布时间】:2012-04-17 10:34:34
【问题描述】:

我有一个文档结构{'text': 'here is text', 'count' : 13, 'somefield': value}

集合有数千条记录,text 键值可能会重复很多次,我想找到具有最高计数值的不同文本,以及应该返回整个文档,我可以按降序对它们进行排序顺序。

distinct 在列表中返回唯一值。

我想使用所有三个函数并且必须返回文档,我还在学习中,没有涉及到mapreduce。

【问题讨论】:

    标签: mongodb pymongo


    【解决方案1】:

    您能否明确说明您想做什么?您要返回具有最高“计数”值的唯一“文本”值的文档吗?

    例如,给定集合:

    > db.text.find({}, {_id:0})
    { "text" : "here is text", "count" : 13, "somefield" : "value" }
    { "text" : "here is text", "count" : 12, "somefield" : "value" }
    { "text" : "here is text", "count" : 10, "somefield" : "value" }
    { "text" : "other text", "count" : 4, "somefield" : "value" }
    { "text" : "other text", "count" : 3, "somefield" : "value" }
    { "text" : "other text", "count" : 2, "somefield" : "value" }
    >
    (I have omitted _id values for brevity)
    

    是否只返回包含具有最高“计数”值的唯一文本的文档?

    { "text" : "here is text", "count" : 13, "somefield" : "value" }
    

    { "text" : "other text", "count" : 4, "somefield" : "value" }
    

    一种方法是使用新聚合框架中的 $group 和 $max 函数。 $group 上的文档可以在这里找到: http://docs.mongodb.org/manual/aggregation/

    > db.text.aggregate({$group : {_id:"$text", "maxCount":{$max:"$count"}}})
    {
        "result" : [
            {
                "_id" : "other text",
                "maxCount" : 4
            },
            {
                "_id" : "here is text",
                "maxCount" : 13
            }
        ],
        "ok" : 1
    }
    

    如您所见,上面没有返回原始文件。如果需要原始文档,则可以进行查询以查找与唯一文本和计数值匹配的文档。

    作为替代方案,您可以先运行“distinct”命令以返回所有不同值的数组,然后使用 sort 和 limit 对每个值运行查询以返回具有最高值“count”的文档. sort() 和 limit() 方法在“高级查询”文档的“游标方法”部分中进行了说明: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-CursorMethods

    > var values = db.runCommand({distinct:"text", key:"text"}).values
    > values
    [ "here is text", "other text" ]
    > for(v in values){var c = db.text.find({"text":values[v]}).sort({count:-1}).limit(1); c.forEach(printjson);}
    {
        "_id" : ObjectId("4f7b50b2df77a5e0fd4ccbf1"),
        "text" : "here is text",
        "count" : 13,
        "somefield" : "value"
    }
    {
        "_id" : ObjectId("4f7b50b2df77a5e0fd4ccbf4"),
        "text" : "other text",
        "count" : 4,
        "somefield" : "value"
    }
    

    目前尚不清楚这是否正是您想要做的,但我希望它至少能给您一些入门的想法。如果我误解了,请更详细地解释您想要执行的确切操作,希望我或社区的其他成员能够帮助您。谢谢。

    【讨论】:

    • 您想只返回包含具有最高“计数”值的唯一文本的文档吗?是的 。我尝试了聚合,似乎 pymongo 不支持聚合,我尝试了 db.command,但仍然失败,我将进行实验,第二种方法似乎很简单,我担心复杂性和往返时间,因为这是遇到的几千到几十万 dosc(目前 10k)。感谢您提供 2 个答案,获取唯一记录需要固定时间(随着文档数量的增加而增加),降序排序也需要 m * n lg ,m 是唯一记录。
    • 聚合命令可以像这样在 PyMongo 中运行: res = db.command({"aggregate":"text", "pipeline":[{"$group" : {"_id": "$text", "maxCount":{"$max":"$count"}}}]}) 有关命令的 PyMongo API 文档在这里:api.mongodb.org/python/current/api/pymongo/… 看起来您的应用程序可能不需要聚合,但是了解如何在 PyMongo 中使用聚合框架以供将来参考仍然很有用。
    • 作为一般建议,通常最好在每次插入时增加一点额外开销,并为每个可以查询的文档添加一个额外的键,而不是进行大量计算(例如 MapReduce 或 Aggregation 命令)每次检索数据时。作为替代方案,可以考虑为每个文档添加一个“isMaxCountforText”键(或等效键)。每次添加或更新文档时,都可以将“count”键与包含相同文本的其他文档进行检查,并相应地更新“isMaxCountforText”。
    猜你喜欢
    • 2016-08-08
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    • 2021-07-27
    • 2015-07-29
    • 2012-12-20
    相关资源
    最近更新 更多