[英]How to match a document with the value of an object attribute in Mongodb
我正在嘗試匹配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"}]});
您將如何進行?
非常感謝。
大衛
您可以嘗試使用點表示法來訪問數組的兩個元素並訪問嵌入式文檔的字段:
db.find({
"profile.languages.name": {
"$in": ["French", "English"]
}
});
實際上,您幾乎是正確的:
db.collection.find({"profile.languages.name":{$in: ["French","English"]} })
由於profile.languages
是子文檔的數組,因此您可以調用子文檔的鍵之一,隨后的查詢將映射到包含該鍵的所有子文檔。
但是,如果沒有正確的索引.explain()
,添加的.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
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
}
請嘗試以下查詢:
解決方案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"]
}
}
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.