mongod 多重嵌套未按预期工作

问题描述 投票:0回答:1

我对这里的 $ 有一些疑问,我的数据库中有以下类型的文档:

 {
 "a": [
   {
    "p": [
      {
        "pid": {
          "CC": "A",
          "SN": "1",
          "KC": "B"
        }
      }
    ]
   }
 ]
 }

当我搜索时:

这按预期工作:

db.collection.find({"a.p.pid": {"CC": "A", "SN": "1" , "KC": "B" }})

那么对于多个SN,也是这样的:

db.collection.find({ 'a.p.pid.CC': 'A', 'a.p.pid.KC': 'B', 'a.p.pid.SN': { "$in": [ "1", "2", "3" ]} })

和:

db.collection.find({"a.p.pid": {$in:[{ "CC": "A","SN": "1","KC": "B" },{ "CC": "A","SN":"2","KC": "B" } ] } } ) 

和:

db.collection.find({"a.p": { $elemMatch: { "pid.CC": "KR", "pid.KC": "A","pid.SN": { "$in": [ "1", "2", "3" ] } } }})

但是,我想知道,为什么这个的工作原理与第一个不同,它返回的结果是空的:

db.collection.find({"a.p.pid": { "CC": "A","KC": "B","SN": { "$in": [ "1", "2", "3" ]}}})

游乐场示例:

游乐场

请指教?

mongodb mongodb-query aggregation-framework
1个回答
0
投票

我需要找到 SN 为 [“1”、“2”、“3”] 和 CC:A 和 KC:B 之一的文档

$elemMatch 是正确的选择。

所以主要问题是为什么这个迭代在 $elemmatch 中按预期工作,但在简单对象元素逗号分隔的情况下不起作用

我希望查询语言有某种正式的规范,但可惜的是,除了简单的英语文档之外,没有什么像 BNF 或任何有意义的替代方案。

$elemMatch查询的语法是:

{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }

它将您的 $elemMatch 查询转换为:

  • <field>
    :“a.p”
  • <query1>
    :{“pid.CC”:{$eq:“A”}}
  • <query2>
    : {"pid.KC": {$eq: "B"}}
  • <query3>
    : {"pid.SN": {"$in": ["1","2","3"]}}

其中每个

<queryX>
被单独解析:

https://www.mongodb.com/docs/manual/reference/operator/query/eq/#syntax

{ <field>: { $eq: <value> } }

https://www.mongodb.com/docs/manual/reference/operator/query/in/#syntax

{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }

现在,为什么另一个查询的行为不一样。让我用明确的

$eq
重写它,使其更明显:

{
  "a.p.pid": {
    $eq: {
      "CC": "A",
      "KC": "B",
      "SN": {
        "$in": [
          "1",
          "2",
          "3"
        ]
      }
    }
  }
}

传递给 $eq 运算符的整个内容是

<value>
,意味着它不会被解析为语言构造。这是数据,而不是命令。在这种情况下,与字段进行比较的值将是

{
  "CC": "A",
  "KC": "B",
  "SN": {
    "$in": [
      "1",
      "2",
      "3"
    ]
  }
}

作为单个 BSON。

这里最棘手的部分是在这种比较中字段的顺序很重要,这很少是理想的而且常常是意想不到的行为。在大多数情况下,您需要使用 $elemMatch 而不是整个对象比较,因为

{a:1, b:2}
{b:2, a:1}
不同。

事实上,并非所有工具都尊重 BSON-JSON 转换后的字段顺序,这只会让事情变得更加混乱。看看https://mongoplayground.net/p/hgsG39MEMvJ

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.