查询MongoDB子文档而不遵守键顺序

时间:2019-02-03 21:53:26

标签: mongodb mongodb-query

我想查询一个子文档。问题是,MongoDB似乎尊重对象键的顺序。因此,如果我执行以下查询,则不会收到任何结果:

db.getCollection('test').find({docId:'tLDmtdeYuG9DiGGrL',optimizeParams:{"deviceType":"mobile","daytime":"night"}})

如果更改optimizeParams的顺序,则会得到结果:

db.getCollection('test').find({docId:'tLDmtdeYuG9DiGGrL',optimizeParams:{"daytime":"night","deviceType":"mobile"}})

现在可以使用点表示法了,但是在这种情况下,我将收到包含两个键的所有文档。但是我只希望只有两个键的文档(没有其他键):

db.getCollection('test').find({docId:'tLDmtdeYuG9DiGGrL',"optimizeParams.deviceType":"mobile","optimizeParams.daytime":"night"})

有没有一种方法可以执行查询而不遵守键顺序?

1 个答案:

答案 0 :(得分:0)

即使有一种方法可以尊重他们的关键命令,我还是建议不要使用它。 JSON文档旨在不遵守关键命令。您应该牢记这一点来设计架构。

对于特定的用例,如果您使用的是3.6版或更高版本,则可以执行以下操作:

db.test.aggregate([{
    $match: {
        "optimizeParams.daytime": "night",
        "optimizeParams.deviceType": "mobile"
    },
},{
    $addFields: {
        count: {
            $size: {
                $objectToArray: "$optimizeParams"
            }
        }
    }
}, {
    $match: {
        count: 2
    }
}])

This answer为我提供了上述解决方案。使用时请牢记索引。

尽管可以做到这一点,但从任何应用程序的角度来看,“仅用这两个键查找文档”似乎都是无关紧要的。这种情况必须代表一些有意义的东西。您可以使用另一个字段来表示该含义,然后使用该字段进行过滤。