我是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)
作为您的预期结果.
一般来说find(),MongoDB 上的任何操作都会返回与查询匹配的所有文档,并且完整地检索所有文档.如果您只想要文档的特定部分,那么您必须在客户端进行该处理.
这是文档数据库和SQL数据库之间的根本区别.通常在文档数据库中,查询返回与其匹配的所有文档,而在SQL数据库中,您可以选择仅返回表的某些部分.当然,除非你说你做了MapReduce,但对你的用例来说这似乎有些过分.
不要阻止你使用MongoDB,但是你工作的任何项目都要考虑NoSQL数据库是否真的符合要求(它们是否满足SQL不能满足的要求),或者你是否仍然更好地使用传统的SQL数据库.