【问题标题】:MongoDB aggregation $elemMatch inside $lookup stage$lookup 阶段内的 MongoDB 聚合 $elemMatch
【发布时间】:2018-07-21 04:10:25
【问题描述】:

我有一个如下所示的 MongoDB 集合:

{
    players: [
        {uuid: "A"},
        {uuid: "B"}
    ]
},
{
    players: [
        {uuid: "A"},
        {uuid: "C"}
    ]
},
{
    players: [
        {uuid: "D"},
        {uuid: "E"}
    ]
}

我想使用之前聚合阶段的结果,现在使用$lookup 阶段查找播放器出现的所有文档:

from: "collection",
pipeline: [
    {
        $match: {
            players: {
                $elemMatch: {
                    uuid: "$playerId" 
                }
            }
            //using "players.uuid": "$playerId" doesn't work either
        }
    }
],
as: "field"

$lookup 阶段的输入如下所示:

{ 
    "playerId" : "A"
}
{ 
    "playerId" : "B"
}
{ 
    "playerId" : "C"
}

此查询在field 中返回一个空数组。似乎$uuid 没有得到正确评估,因为如果我将$uuid 与硬编码值(例如A)交换,此查询将返回结果。

我也尝试过使用let 属性,这给了我相同的结果。 我做错了什么?

【问题讨论】:

  • 你能用示例文档从集合中发布吗
  • 我帖子的顶部包含示例文档。

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

使用您提供的文件。我相信这可能对你有用:

我使用$lookup 对包含playerId 的集合进行连接,这会创建一个名为fieldarray。然后我使用$unwindfieldplayer 中提取所有数组元素。最后,我使用$cond 来交叉检查两个值是否匹配。

db.getCollection('foo').aggregate([
{ $lookup : {
    from: "bar",
    localField: "players.uuid",
    foreignField: "playerId",
    as: "field"
    } },
    { $unwind : "$players" },
    { $unwind : "$field" },
    { $project : { 
      "players": 1, 
      "field" : 1, 
      "isMatch": { 
      "$cond": [ { "$eq": ["$players.uuid", "$field.playerId"] }, 1, 0 ] 
      } } }
    ])

我故意让输出变得冗长..

/* 1 */
{
    "_id" : ObjectId("5a7f534b337e8d2b97ff2ffb"),
    "players" : {
        "uuid" : "A"
    },
    "field" : {
        "_id" : ObjectId("5a7f5374337e8d2b97ff2ffe"),
        "playerId" : "A"
    },
    "isMatch" : 1.0
}

/* 2 */
{
    "_id" : ObjectId("5a7f534b337e8d2b97ff2ffb"),
    "players" : {
        "uuid" : "A"
    },
    "field" : {
        "_id" : ObjectId("5a7f539b337e8d2b97ff2fff"),
        "playerId" : "B"
    },
    "isMatch" : 0.0
}

/* 3 */
{
    "_id" : ObjectId("5a7f534b337e8d2b97ff2ffb"),
    "players" : {
        "uuid" : "B"
    },
    "field" : {
        "_id" : ObjectId("5a7f5374337e8d2b97ff2ffe"),
        "playerId" : "A"
    },
    "isMatch" : 0.0
}

/* 4 */
{
    "_id" : ObjectId("5a7f534b337e8d2b97ff2ffb"),
    "players" : {
        "uuid" : "B"
    },
    "field" : {
        "_id" : ObjectId("5a7f539b337e8d2b97ff2fff"),
        "playerId" : "B"
    },
    "isMatch" : 1.0
}

/* 5 */
{
    "_id" : ObjectId("5a7f5356337e8d2b97ff2ffc"),
    "players" : {
        "uuid" : "A"
    },
    "field" : {
        "_id" : ObjectId("5a7f5374337e8d2b97ff2ffe"),
        "playerId" : "A"
    },
    "isMatch" : 1.0
}

/* 6 */
{
    "_id" : ObjectId("5a7f5356337e8d2b97ff2ffc"),
    "players" : {
        "uuid" : "A"
    },
    "field" : {
        "_id" : ObjectId("5a7f53a8337e8d2b97ff3000"),
        "playerId" : "C"
    },
    "isMatch" : 0.0
}

/* 7 */
{
    "_id" : ObjectId("5a7f5356337e8d2b97ff2ffc"),
    "players" : {
        "uuid" : "C"
    },
    "field" : {
        "_id" : ObjectId("5a7f5374337e8d2b97ff2ffe"),
        "playerId" : "A"
    },
    "isMatch" : 0.0
}

/* 8 */
{
    "_id" : ObjectId("5a7f5356337e8d2b97ff2ffc"),
    "players" : {
        "uuid" : "C"
    },
    "field" : {
        "_id" : ObjectId("5a7f53a8337e8d2b97ff3000"),
        "playerId" : "C"
    },
    "isMatch" : 1.0
}

【讨论】:

  • 这是一个我想加入的字段名称,但这似乎不起作用。
  • @Joba 你能不能也请用这个集合的例子更新你的 OP。然后我可以设置一个测试,看看我是否可以提供帮助。目前我只有一半的问题:-)
  • 更新了 OP 并澄清了我的例子
  • 但是为什么按主题启动的初始请求不起作用?
猜你喜欢
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 2018-08-06
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多