簡體   English   中英

屬性順序更改時,Mongo DB子文檔查詢失敗

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM