MongoDB - 过滤结果集中内部数组的内容

Mar*_*oni 13 filter mongodb

我是MongoDB的新手,我不知道如何解决下一个问题:

我有这样的文档集合:

{
 "URL": "www.stackoverflow.com",
 "TAGS": [
         {"NAME": "question", "VOTES": 3},
         {"NAME": "answer", "VOTES": 5},
         {"NAME": "problem", "VOTES": 2}
         ]
}
Run Code Online (Sandbox Code Playgroud)

首先,我想要所有包含列表中所有标签的Urls.我通过查询解决了这个问题:

db.links.find( { "Tags.Name" : { $all: ["question","answers"] } } );
Run Code Online (Sandbox Code Playgroud)

但是这个查询返回了整个正确的文档,只有正确的文档,只有我要求的标记.

我正在寻找的结果是:

{
 "URL": "www.stackoverflow.com",
 "TAGS": [{"NAME": "question", "VOTES": 3},
         {"NAME": "answer", "VOTES": 5}]
}
Run Code Online (Sandbox Code Playgroud)

并不是:

{
 "URL": "www.stackoverflow.com",
 "TAGS": [{"NAME": "question", "VOTES": 3},
         {"NAME": "answer", "VOTES": 5},
         {"NAME": "problem", "VOTES": 2}]
}
Run Code Online (Sandbox Code Playgroud)

因为我只要求标签["问题","答案"].

我想过使用MapReduce或解析结果集,但我不知道它是否是解决问题的正确方法.也许有一个内置函数可以更有效地解决它.

谢谢!

Ahm*_*DAL 19

您可以使用聚合框架MongoDB.

如果你的馆藏中有一份文件,那就是;

{
 "URL": "www.stackoverflow.com",
 "TAGS": [
         {"NAME": "question", "VOTES": 3},
         {"NAME": "answer", "VOTES": 5},
         {"NAME": "problem", "VOTES": 2}
         ]
}
Run Code Online (Sandbox Code Playgroud)

并且你想过滤一些数组元素,你可以使用聚合样本;

db.sof_table.aggregate
([
{$unwind:'$TAGS'}, 
{$match:{'TAGS.NAME':{$in:['answer','question']}}},
{$group:{_id:'$URL',TAGS:{$push:'$TAGS'}}}
])
Run Code Online (Sandbox Code Playgroud)

这将导致;

{
    "result" : [
        {
            "_id" : "www.stackoverflow.com",
            "TAGS" : [
                {
                    "NAME" : "question",
                    "VOTES" : 3
                },
                {
                    "NAME" : "answer",
                    "VOTES" : 5
                }
            ]
        }
    ],
    "ok" : 1
}
Run Code Online (Sandbox Code Playgroud)

作为您的预期结果.


Rob*_*obV 9

一般来说find(),MongoDB 上的任何操作都会返回与查询匹配的所有文档,并且完整地检索所有文档.如果您只想要文档的特定部分,那么您必须在客户端进行该处理.

这是文档数据库和SQL数据库之间的根本区别.通常在文档数据库中,查询返回与其匹配的所有文档,而在SQL数据库中,您可以选择仅返回表的某些部分.当然,除非你说你做了MapReduce,但对你的用例来说这似乎有些过分.

不要阻止你使用MongoDB,但是你工作的任何项目都要考虑NoSQL数据库是否真的符合要求(它们是否满足SQL不能满足的要求),或者你是否仍然更好地使用传统的SQL数据库.


Mar*_*oni -1

谢谢罗伯特。我意识到我正在寻找的功能目前尚未实现。这是问题的链接。我希望MongoDB社区能够在短时间内实现它。谢谢!

  • 注意:虽然 jira 问题已解决。该解决方案并不能解决问题。它只检索第一个匹配的子文档。[$elemMatch](http://docs.mongodb.org/manual/reference/operator/projection/elemMatch) (2认同)