MongoDb聚合对应用程序进行分组和排序

时间:2018-12-07 13:04:20

标签: mongodb aggregation-framework

有些文档具有以下结构:

{"appId":<id>,"time":<number>}

对于该示例,我们假设我们有:

{"appId":"A","time":1}
{"appId":"A","time":3}
{"appId":"A","time":5}
{"appId":"B","time":1}
{"appId":"B","time":2}
{"appId":"B","time":4}
{"appId":"B","time":6}

是否可以按appId对文档进行分组,每个组按时间排序,并且所有结果从该组的最新时间开始显示,例如:

{"appId":"B","time":6}
{"appId":"B","time":4}
{"appId":"B","time":2}
{"appId":"B","time":1}

{"appId":"A","time":5}
{"appId":"A","time":3}
{"appId":"A","time":1}

我尝试了以下查询:

collection.aggregate([{"$group":{"_id":{"a":"$appId"},"ttt":{"$max":"$time"}}},
{"$sort":{"_id.ttt":-1,"time":-1}}])

但是我上次仅收到特定appId-> 2的结果,该查询更改了数据的结构。 我想保留文档的结构,仅像示例一样对它们进行分组和排序。

2 个答案:

答案 0 :(得分:1)

您可以尝试以下汇总:

db.collection.aggregate([
    {
        $sort: { time: -1 }
    },
    {
        $group: {
            _id: "$appId",
            max: { $max: "$time" },
            items: { $push: "$$ROOT" }
        }
    },
    {
        $sort: { max: -1 }
    },
    {
        $unwind: "$items"
    },
    {
        $replaceRoot: {
            newRoot: "$items"
        }
    }
])

您可以在分组之前$sort,以在每个组中获得正确的顺序。然后,您可以在分组时使用特殊变量$$ROOT来捕获整个原始对象。在下一步中,您可以按$max值排序,并与$unwind一起使用$replaceRoothttps://www.facebook.com/tr?noscript=1&ev=ViewContent&id=xy&cd%5Bvalue%5D=&cd%5Bcurrency%5D=&cd%5Bcontent_name%5D=open%20article&cd%5Bcontent_type%5D=&cd%5Bcontent_ids%5D=&dt=o4haxxaf7ij6ugv6b3p7cy2qybh9e8rd来获取相同数量的文档并将原始形状提升到根级别。

答案 1 :(得分:1)

查看下面的查找和排序操作是否适用于您的真实数据。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div class="list__wrapper">
    <ul class="list">
        <li class="init">Option 0</li>
        <li data-value="value 1">Option 1</li>
        <li data-value="value 2">Option 2</li>
        <li data-value="value 3">Option 3</li>
    </ul>
</div>

如果这是一个庞大的集合,并且这将是重复查询,请确保在这两个字段上创建复合索引。