当属性顺序更改时,Mongo DB子文档查询失败

时间:2015-07-22 04:49:05

标签: mongodb mongodb-query

使其变得非常简单

这是我的示例文档'地址'

ORDER_CANCELLED=Order with order id {order.id} is cancelled.

查询1

name : "User1",address : {street : "Street1", colony : "Colony1"} - 回复文件

查询2

db.address.find({ "address" : {street : "Street1", colony : "Colony1"} } - 返回0行。

只是属性顺序被更改,查询失败。

P.S:子文档是动态的,可以有任意数量的属性。所以请不要建议DOT功能

以另一种方式提问

db.address.find({ "address" : {colony : "Colony1", street : "Street1"} }

当我不知道其中一个属性

的实际结构时,如何查询这样的文档

1 个答案:

答案 0 :(得分:-1)

这是因为您当前表单中的查询正在寻找"完全匹配"该文件。因此,即使文档有其他字段,查询也不匹配。

改为使用$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
        }
    }
])

然后,您不是要查询"完全匹配",请使用"dot notation"指定字段的完整路径:

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
    }
}