组条目并获取组内的最低和最高值(Group entries and get lowest and highest values within group)

我有一个包含类似于以下数据的集合:

{ processName: "TestImport", processId: 1, message: "Started", time: 1486609206370 } { processName: "TestImport", processId: 1, message: "Finished", time: 1486609207388 } { processName: "TestImport", processId: 2, message: "Started", time: 1486779281773 } { processName: "TestImport", processId: 2, message: "Finished", time: 1485992810029} { processName: "SomeOtherImport", processId: 1, message: "Started", time: 1486779281773 } { processName: "SomeOtherImport", processId: 1, message: "Finished", time: 1487993829281 }

所以它基本上包含来自不同进程的多条消息。 每个进程都通过它的processName和一个连续的processId来识别。

现在我想创建一个选择最新进程的查询,因此ID最高的进程会返回最早和最后一条消息的时间,以及最后一条消息。

我已经接近这个使用aggregate并将其分组如下:

db.status_history.aggregate([ { $group: { _id: { name: "$processName", id: "$processId" }, processId: { $last: "$processId" }, message: { $last: "$message" }, startTime: { $first: "$time" }, endTime: { $last: "$time" } } }]);

但是像这样,我不仅获得每个进程具有最高ID的条目,而且每个ID都有一个条目(尽管具有正确的值):

{ processName: "TestImport", processId: 1, message: "Finished", startTime: 1486609206370, endTime: 1486609207388 } { processName: "TestImport", processId: 2, message: "Finished", startTime: 1486779281773, endTime: 1485992810029 } { processName: "SomeOtherImport", processId: 1, message: "Finished", startTime: 1486779281773, endTime: 1487993829281 }

我需要更改哪些内容才能获得最高ID的结果? 喜欢这个:

{ processName: "TestImport", processId: 2, message: "Finished", startTime: 1486779281773, endTime: 1486923811716 } { processName: "SomeOtherImport", processId: 1, message: "Finished", startTime: 1486779281773, endTime: 1487993829281 }

I have a collection that contains data that looks similar to this:

{ processName: "TestImport", processId: 1, message: "Started", time: 1486609206370 } { processName: "TestImport", processId: 1, message: "Finished", time: 1486609207388 } { processName: "TestImport", processId: 2, message: "Started", time: 1486779281773 } { processName: "TestImport", processId: 2, message: "Finished", time: 1485992810029} { processName: "SomeOtherImport", processId: 1, message: "Started", time: 1486779281773 } { processName: "SomeOtherImport", processId: 1, message: "Finished", time: 1487993829281 }

So it basically contains multiple messages from different processes. Each process is identified via it's processName and a consecutive processId.

Now I want to make a query that selects the latest process, so the one with the highest ID and returns the time of the earliest and the last message, as well as the last message.

I have come close to this by using aggregate and grouping it like this:

db.status_history.aggregate([ { $group: { _id: { name: "$processName", id: "$processId" }, processId: { $last: "$processId" }, message: { $last: "$message" }, startTime: { $first: "$time" }, endTime: { $last: "$time" } } }]);

But like this, I do not only get the entry with the highest ID for each process, but one entry for each ID (with the correct values though):

{ processName: "TestImport", processId: 1, message: "Finished", startTime: 1486609206370, endTime: 1486609207388 } { processName: "TestImport", processId: 2, message: "Finished", startTime: 1486779281773, endTime: 1485992810029 } { processName: "SomeOtherImport", processId: 1, message: "Finished", startTime: 1486779281773, endTime: 1487993829281 }

What do I need to change so that I will only get results for respectively the highest ID? Like this:

{ processName: "TestImport", processId: 2, message: "Finished", startTime: 1486779281773, endTime: 1486923811716 } { processName: "SomeOtherImport", processId: 1, message: "Finished", startTime: 1486779281773, endTime: 1487993829281 }

最满意答案

第一组可以按名称和ID应用排序 ,然后再按名称分组并选择第一个匹配的信息。

db.status_history.aggregate([ { $group: { _id: { name: "$processName", id: "$processId" }, processId: {$last: "$processId"}, message: {$last: "$message"}, startTime: {$first: "$time"}, endTime: {$last: "$time"} } }, {$sort:{"_id.name":1, "_id.id":-1}}, { $group: { _id: "$_id.name", processId: {$first: "$processId"}, message: {$first: "$message"}, startTime: {$first: "$startTime"}, endTime: {$first: "$endTime"} } } ]);

After first group can apply sort by name and id and then again group by name and select first matching information.

db.status_history.aggregate([ { $group: { _id: { name: "$processName", id: "$processId" }, processId: {$last: "$processId"}, message: {$last: "$message"}, startTime: {$first: "$time"}, endTime: {$last: "$time"} } }, {$sort:{"_id.name":1, "_id.id":-1}}, { $group: { _id: "$_id.name", processId: {$first: "$processId"}, message: {$first: "$message"}, startTime: {$first: "$startTime"}, endTime: {$first: "$endTime"} } } ]);

更多推荐