首页 > 解决方案 > 在不考虑键顺序的情况下查询 MongoDB 子文档

问题描述

我想查询子文档。问题是,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"})

有没有办法在不尊重键顺序的情况下执行查询?

标签: mongodbmongodb-query

解决方案


即使有办法尊重他们的关键命令,我也建议不要使用它。JSON 文档旨在不尊重关键顺序。您应该考虑到这一点来设计您的架构。

对于您的特定用例,如果您使用的是 3.6 或更高版本,则可以这样做:

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

这个答案帮助我解决了上述问题。使用时请牢记索引。

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


推荐阅读