我正在尝试匹配mongoDB中的某些文档:
我的文档模型:
profile: {
languages: [
{"name": "French", "level": 1},
{"name": "English", "level": 2},
{"name": "Spanish", "level": 4}
]
}
我(我)可以搜索我的结果集:
lang = ["French", "English"];
objLang = [
{name: "French"},
{name: "English"}
];
我需要的是db.find()所有匹配至少一种语言的文档,例如:
profile.languages.name = "French"
或
profile.languages.name = "English"
我的意思是,如果我在我的选项集中有法语或英语,我需要让所有拥有其语言数组元素的用户,其名称与我的选项之一匹配,无论语言的级别如何。
所以,除非我错了,否则我不能做
db.find({"profile.languages": {$in: [{name: "French"}, {name: "English"}]});
你会怎么做?
非常感谢。
大卫
答案 0 :(得分:1)
您可以尝试使用 dot notation 访问数组的两个元素并访问嵌入文档的字段:
db.find({
"profile.languages.name": {
"$in": ["French", "English"]
}
});
答案 1 :(得分:1)
实际上,你几乎是对的:
db.collection.find({"profile.languages.name":{$in: ["French","English"]} })
由于profile.languages
是一个子文档数组,因此可以调用其中一个子文档的键,后续查询将映射到包含该键的所有子文档。
但是,如果没有正确的索引,添加的.explain()
会显示一些非常难看的内容:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.languages",
"indexFilterSet" : false,
"parsedQuery" : {
"profile.languages.name" : {
"$in" : [
"English",
"French"
]
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"profile.languages.name" : {
"$in" : [
"English",
"French"
]
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
}
}
(serverInfo
被忽略了。)
因此,为了使此查询更有效,您需要在要查询的字段上创建索引:
db.languages.ensureIndex({"profile.languages.name":1})
现在增加的解释告诉我们,匹配的文件是通过索引识别的:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.languages",
"indexFilterSet" : false,
"parsedQuery" : {
"profile.languages.name" : {
"$in" : [
"English",
"French"
]
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"profile.languages.name" : 1
},
"indexName" : "profile.languages.name_1",
"isMultiKey" : true,
"direction" : "forward",
"indexBounds" : {
"profile.languages.name" : [
"[\"English\", \"English\"]",
"[\"French\", \"French\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"ok" : 1
}
答案 2 :(得分:1)
请尝试以下查询:
解决方案1:
db.collection.aggregate([
{
$unwind:"$profile.languages"
},
{
$match:{"profile.languages.name":{"$in":["French", "English"]}}
},
{
$group:{_id: "$_id", profile:{"$push":"$profile.languages"}}
}
])
解决方案2:
db.collection.find(
{
"profile.languages.name":
{
"$in": [ "English", "French"]
}
}
);