mongodb - 在 mongodb 聚合框架中组合多个 match() 结果

标签 mongodb aggregation-framework

我得到以下查询:

db.getCollection('Messages').aggregate(
    { 
    $match : 
        { 
            "header.MessageType" : { $in: ["04"] },
        }

    },
    {
        $project:
          {
             _id: '$_id',
             header: '$header',
             content: '$content',
             q0: { $arrayElemAt: [ "$content.Changes", 0 ] },
             q1: { $arrayElemAt: [ "$content.Changes", 1 ] },
             q2: { $arrayElemAt: [ "$content.Changes", 2 ] },
             q3: { $arrayElemAt: [ "$content.Changes", 3 ] },
             q4: { $arrayElemAt: [ "$content.Changes", 4 ] },
             q5: { $arrayElemAt: [ "$content.Changes", 5 ] },
          }
    },
    {
        $match : 
        { 
            "q0":"1"
        }
    },
    { 
        $sort : { "sequenceID" : -1, } 
    },
    { 
        $limit : 1
    }
);

这给了我以下结果:

/* 1 */
{
    "_id" : ObjectId("57288ecb53f65928c4ba4995"),
    "header" : {
        "MessageType" : "04",
        ...
    },
    "content" : {
        ...
    },
    "q0" : "1",
    "q1" : "0",
    "q2" : "1",
    "q3" : "0",
    "q4" : "0",
    "q5" : "0"

查询为我提供了最新的文档(根据 sequenceID),其“q0”绝对等于 1(其他 qx 字段可能为 0 或 1)。 我想对 q1,q2,...,q5 做同样的事情。换句话说,我想要一个包含 6 条记录的结果,每条记录代表其 'qn' (n=0..5) 记录肯定为 '0' 的最新文档。

是否可以将以下部分重复 6 次(对于 $match 部分中的不同 qx 值)然后将它们组合起来?

{
    $match : 
    { 
        "q0":"1"
    }
},
{ 
    $sort : { "sequenceID" : -1, } 
},
{ 
    $limit : 1
}

或者对此有更好的解决方案吗?

--- 编辑(添加了一些样本[和简化]数据):

/* 1 */
{
    "_id" : ObjectId("57288fa553f65928c4bf4b2b"),
    "header" : {
        "MessageType" : "04"
    },
    "content" : {
        "Changes" : [ 
            "0", 
            "1", 
            "1", 
            "1", 
            "1", 
            "0"
        ]
    },
    "sequenceID" : NumberLong(369851),
    "messageDate" : 13950214
}

/* 2 */
{
    "_id" : ObjectId("57288fa453f65928c4bf4863"),
    "header" : {
        "MessageType" : "04"
    },
    "content" : {
        "Changes" : [ 
            "0", 
            "0", 
            "1", 
            "0", 
            "0", 
            "0"
        ]
    },
    "sequenceID" : NumberLong(369139),
    "messageDate" : 13950214
}

/* 3 */
{
    "_id" : ObjectId("57288fa353f65928c4bf43c2"),
    "header" : {
        "MessageType" : "04"
    },
    "content" : {
        "Changes" : [ 
            "0", 
            "1", 
            "0", 
            "0", 
            "0", 
            "0"
        ]
    },
    "sequenceID" : NumberLong(367953),
    "messageDate" : 13950214
}

每个文档表示一个或多个(最多 6 个)修改。在 q0..q5 字段中可以看到修改。作为输出,我需要的是每个 qx 字段的最新更改。文档的顺序可以由“sequenceID”字段确定。换句话说,如果我(逻辑上做一个)或结果中所有文档的 q0..q5,它应该是 ["1","1","1","1","1","1"].

最佳答案

实际上,aggregate 函数被称为管道,只是因为它将数据从一个聚合运算符通过管道传输到另一个,而您需要多少管道才能获得最终结果。

e.g.
$match -> $project -> $group -> $sort -> $match -> $sort -> $limit -> $project

您可以多次使用任何运算符。

db.getCollection('Messages').aggregate(
 [
  { $match : { "header.MessageType" : { $in: ["04"] }}},
  {
        $project:
          {
             _id: '$_id',
             "MessageType": '$header.MessageType',
             q0: { $arrayElemAt: [ "$content.Changes", 0 ] },
             q1: { $arrayElemAt: [ "$content.Changes", 1 ] },
             q2: { $arrayElemAt: [ "$content.Changes", 2 ] },
             q3: { $arrayElemAt: [ "$content.Changes", 3 ] },
             q4: { $arrayElemAt: [ "$content.Changes", 4 ] },
             q5: { $arrayElemAt: [ "$content.Changes", 5 ] },
          }
  },
  {$match : { "q0" : "0" } },
  {$sort : { "q1" : -1}},
  {$match : {"q3" : "1"}}
 ]
)

现在最后要添加的是添加 6 个匹配子句,即使您使用的是索引也会减慢您的查询速度,如果您的集合很大,则需要一些时间从聚合中传输所有数据管道。因此请明智地使用此管道。

关于mongodb - 在 mongodb 聚合框架中组合多个 match() 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37110869/

相关文章:

mongodb - 导出 Mongodb 图表

MongoDb.展平内部数组

mongodb - Mongodb 的 Golang mgo 聚合

java - 如何在Spring Java应用程序中缓存图像文件?

MongoDB 在 CentOS 7 上作为服务启动失败

mongodb - 从展开的数组中获取最大值

mongodb - 在 mongodb 中查找字段的所有非不同值

MongoDB 聚合使用 $match 和 $expr 以及数组

node.js - 居住在 Mongoose 中

mongodb - spring-data-mongodb 相当于 jackson 中的@JsonUnwrapped