当字段顺序未知时,嵌入文档上的完全匹配

时间:2016-05-18 15:26:37

标签: mongodb mongodb-query

doc说:

  

要在整个嵌入文档中指定相等匹配,请使用   { <field>: <value> }所在的查询文档<value>   要匹配的文件。嵌入式文档中的平等匹配需要   与指定<value>完全匹配,包括字段顺序。

使用点符号并不是一个完全令人满意的解决方案,因为它还将文档嵌入文档的字段数多于所需的字段。我可能不知道哪些是其他可能的字段,因此无法明确排除不需要的字段。

也不需要查询每个可能的字段组合,因为我不想写(#fields)!查询。

当我不关心字段的顺序时,如何才能找到包含嵌入式文档的文档?

例如,假设遵循此模式的文档集合,但inner字段的顺序未知或可能会有所不同,具体取决于插入方式/时间:

{
_id: ObjectId()
inner: {
    some_field: some_value,
    some_other_field: some_other_value
    }
}

如果我想将包含inner个对象的所有文档都设为{some_field: some_value, some_other_field: some_other_value},我会希望

db.collection.find({inner:{some_field: some_value, some_other_field: some_other_value}})

但我会错过inner对象为{some_other_field: some_other_value, some_field: some_value}的文档。

使用点符号,如

db.collection.find({"inner.some_field": some_value, "inner.some_other_field": some_other_value})

将匹配我感兴趣的所有文件,但也包括

等噪音
{
_id: ObjectId()
inner: {
    some_field: some_value,
    some_other_field: some_other_value,
    some_undesired_field: some_undesired_value
    }
}

2 个答案:

答案 0 :(得分:1)

尝试传递您要查找的文档。它适用于我,但字段的顺序也很重要。

db.collection.find({“inner”:{“some_field”:some_value,“some_other_field”:some_other_value}})。pretty();

我刚刚读到该字段顺序未知。因此,您必须使用$或列出可能性,例如:

db.collection.find({$ or:[{“inner”:{“some_field”:some_value,“some_other_field”:some_other_value}},{“inner”:{“some_other_field”:some_other_value,“some_field”: some_value}}]})。pretty();

答案 1 :(得分:0)

构建此问​​题的一种方法是,您希望这两个字段(按任意顺序)而结果中没有其他字段

点符号解决了问题的第一部分,您可以通过确保inner只有2个字段来解决第二部分。

db.collection.find({
  "inner.some_field": some_value,
  "inner.some_other_field": some_other_value,
  $where: function() { return Object.keys(this.inner).length === 2 }  
})

我相信这是最简单的方法。这种方法的缺点是$where可能因为此处详述的原因而变慢:Mongodb Query based on number of fields in a record