【问题标题】:How to query an array of documents in MongoDB如何在 MongoDB 中查询文档数组
【发布时间】:2018-04-05 03:24:50
【问题描述】:

我有一组像这样的对象:

{
    "actions": [{
        "help": {
            "messages": [{}, {}]
        }
    }, {
        "animals": [{
            "sea": {
                "messages": [{}, {}]
            }
        }, {
            "land": {
                "messages": [{}, {}]
            }
        }]
    }]
}

我正在尝试从每个元素中获取 messages 数组。 (只匹配一个)

我尝试过类似的方法:

db.getCollection('responses').find({"actions": "help"})

db.getCollection('responses').find({"actions.animals": "sea"})

没有运气,因为我仍然得到一个空数组。

如果这不可能,我愿意提供替代方案。

我一直在寻找类似的问题,例如:Mongo db - Querying nested array and objects,但在那个问题中,他们正在寻找“消息”对象(在我的情况下)中的特定元素。与其他问题相同:Query for a field in an object in array with Mongo? 他们在哪里使用$elementMatch,我认为它不符合我的需求。

我认为在 Mongo 教程中:Query array of documents 可能会有所帮助,但同样,它们的结构与我的相似,但它们具有 help 元素的属性,例如:

{
    "actions": [{
        "action": "help",
        "messages": [{}, {}]
    }, {
        "action": "animals",
        "classifications": [{
            "classification": "sea",
            "messages": [{}, {}]
        }, {
            "classification": "land",
            "messages": [{}, {}]
        }]
    }]
}

这是使它工作的唯一方法吗?或者我还能保持原来的结构吗?

编辑

尝试@Graciano 的回答后,我得到以下信息:

db.getCollection('responses').aggregate([{
    $project: { "messages":  "$actions.animals.sea.messages" }
}])

结果:

/* 1 */
{
    "_id" : ObjectId("5ac42e65734d1d5beda1f99b"),
    "messages" : [ 
        [ 
            [ 
                {
                    "type" : 0,
                    "speech" : "There are a lot of sea animals, to name a few: "
                }, 
                {
                    "type" : 0,
                    "speech" : "Whale\nFishes\nSharks"
                }
            ]
        ]
    ]
}

现在要解决的错误是它必须是单个数组,而不是消息数组的数组......如何解决这个问题?

【问题讨论】:

  • 您能否提供一个包含混合数据的样本数据集(其中包含空数组和非空数组)。我在您的示例数据集中没有看到 speech 键。
  • 刚刚添加了一个对您的查询进行编辑的答案,请检查并告诉我是否可行。

标签: arrays mongodb


【解决方案1】:

我刚刚更新了您的查询,现在它看起来像这样:

db.collection.aggregate([
{$project: { "messages":  "$actions.animals.sea.messages" }},
{$unwind: "$messages"},
{$unwind: "$messages"}

])

结果将是:

{
 "_id" : ObjectId("5ac5b80dd39d9355012f6af3"),
 "messages" : [ 
    {
        "type" : 0,
        "speech" : "There are a lot of sea animals, to name a few: "
    }, 
    {
        "type" : 0,
        "speech" : "Whale\nFishes\nSharks"
    }
  ]
}

现在您将只得到一个数组,您只需分别$unwind 数组。

【讨论】:

    【解决方案2】:

    如果您只需要消息,您可以使用聚合并从所需元素创建一个数组

    db.collection.aggregate([
      {$project: { items:  "$actions."+parameter+".messages" },
      {$unwind: "$messages"},
      {$unwind: "$messages"}
    }])
    

    【讨论】:

    • 我需要消息,但只是来自匹配的操作,即如果将help 发送到查询,那么我可能只会从中获取help 消息数组。在这种情况下,可能不需要$concatArrays,对吧?
    • 它有效,但是您的代码中有一些拼写错误,我可以在您的答案中更正它吗?还是您想自己更正?它还在数组中创建了第二个数组
    • 更正了错别字,让我对我的问题进行编辑,以便您查看我得到的输出。
    • 不清楚您想要的输出方式。正如@Rahul Raj 在下面评论的那样,您只需要添加$unwind 操作
    猜你喜欢
    • 2019-08-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多