[英]Mongo DB subdocument query fails when attribute order changes
使其非常簡單
這是我的示例文檔“地址”
name : "User1",address : {street : "Street1", colony : "Colony1"}
查詢1
db.address.find({ "address" : {street : "Street1", colony : "Colony1"} }
-返回文檔
查詢2
db.address.find({ "address" : {colony : "Colony1", street : "Street1"} }
-返回0行。
只是屬性順序被更改,查詢失敗。
PS:子文檔是動態的,可以具有任意數量的屬性。 所以請不要建議DOT功能
用另一種方式問
name : "User1",address : {street : "Street1", colony : "Colony1"}
name : "User1",address : {path: "Patth1", venue : "Venue1"}
當我不知道屬性之一的實際結構時,如何查詢此類文檔
那是因為您在當前表單中的查詢正在尋找文檔的“完全匹配”。 因此,即使文檔具有其他字段,查詢也將不匹配。
使用$elemMatch
代替:
db.address.find({
"address" : {
"$elemMatch": { "colony": "Colony1", "street": "Street1" }
}
})
這將對指定的數組屬性執行“查詢”。 元素的“順序”甚至是“附加的”元素都沒有關系,就像普通查詢條件一樣。
$elemMatch
運算符允許“多個”條件匹配數組中的子文檔。 這與對每個元素使用“點符號”不同,后者只是測試數組中至少“一個”元素是否符合任一條件。 這要求在同一文檔中滿足“所有”條件。
下面是它的工作原理:
db.address.insert([
{
"matched": "expected",
"address": [
{ "street": "Street1", "colony": "Colony1" }
]
},
{
"matched": "not expected",
"address": [
{ "street": "Street2", "colony": "Colony1" }
]
},
{
"matched": "expected",
"address": [
{ "colony": "Colony1", "street": "Street1", "another": 1 }
]
}
])
然后查詢:
db.address.find({
"address": {
"$elemMatch": {
"colony": "Colony1", "street": "Street1"
}
}
})
讓您:
{
"matched" : "expected",
"address" : [
{
"street" : "Street1",
"colony" : "Colony1"
}
]
}
{
"matched" : "expected",
"address" : [
{
"colony" : "Colony1",
"street" : "Street1",
"another": 1
}
]
}
因此,如果您不明白這一點,那么您的文檔甚至根本就沒有“數組”。 像這樣:
db.address.insert([
{
"matched": "expected",
"address": {
"street": "Street1", "colony": "Colony1"
}
},
{
"matched": "not expected",
"address": {
"street": "Street2", "colony": "Colony1"
}
},
{
"matched": "expected",
"address": {
"colony": "Colony1", "street": "Street1", "another": 1
}
}
])
然后,您可以使用“點符號”來指定字段的完整路徑,而不是查詢“完全匹配”:
db.address.find({
"address.street": "Street1",
"address.colony": "Colony1"
})
它以任何順序匹配文檔中的子文檔元素。
{
"matched" : "expected",
"address" : {
"street" : "Street1",
"colony" : "Colony1"
}
}
{
"matched" : "expected",
"address" : {
"colony" : "Colony1",
"street" : "Street1",
"another" : 1
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.