【问题标题】:MongoDB not querying `null` within a array at a given posision correctlyMongoDB 未正确查询给定位置的数组中的“null”
【发布时间】:2016-12-15 18:14:56
【问题描述】:

我很难理解为什么在 mongodb 中处理查询中的空值和数组索引时会发生以下情况。

假设我们有以下内容:

> db.test.find()
{ "_id" : ObjectId("5852da24507d8c27f4e3c357"), "item" : null }
{ "_id" : ObjectId("5852da2d507d8c27f4e3c358"), "item" : { "something" : true } }
{ "_id" : ObjectId("5852da33507d8c27f4e3c359") }

当我尝试查找为空的项目时,我得到 ObjectId("5852da24507d8c27f4e3c357")ObjectId("5852da33507d8c27f4e3c359"),这与基于 https://docs.mongodb.com/v3.2/tutorial/query-for-null-fields/ 的预期一致

> db.test.find({"item" : null})
{ "_id" : ObjectId("5852da24507d8c27f4e3c357"), "item" : null }
{ "_id" : ObjectId("5852da33507d8c27f4e3c359") }

但是当我尝试在一个给定索引的数组中做同样的事情时,结果完全不同:

假设我们有以下内容:

> db.test.find()
{ "_id" : ObjectId("5852dbe1507d8c27f4e3c35c"), "a" : [ { "something" : true }, { "something" : true }, null ] }
{ "_id" : ObjectId("5852dbf4507d8c27f4e3c35d"), "a" : [ { "something" : true }, { "something" : true }, { "something" : true } ] }
{ "_id" : ObjectId("5852dbfb507d8c27f4e3c35e"), "a" : [ { "something" : true }, { "something" : true } ] }

但是如果我根据 2 的索引为空进行查询,我们仍然会返回所有文档:

> db.test.find({"a.2": null})
{ "_id" : ObjectId("5852dbe1507d8c27f4e3c35c"), "a" : [ { "something" : true }, { "something" : true }, null ] }
{ "_id" : ObjectId("5852dbf4507d8c27f4e3c35d"), "a" : [ { "something" : true }, { "something" : true }, { "something" : true } ] }
{ "_id" : ObjectId("5852dbfb507d8c27f4e3c35e"), "a" : [ { "something" : true }, { "something" : true } ] }

这对我来说似乎不像预期的那样工作?但是我们可以看到索引位置正常工作,因为我们可以执行以下查询:

> db.test.find({"a.2": {something:true}})
{ "_id" : ObjectId("5852dbf4507d8c27f4e3c35d"), "a" : [ { "something" : true }, { "something" : true }, { "something" : true } ] }

这是 mongodb 中的一个错误并处理数组和空值吗?

【问题讨论】:

  • 我不确定这是否是预期的行为,也许是一个错误,所以我创建了JIRA SERVER-27442

标签: arrays mongodb mongodb-query mongo-shell


【解决方案1】:

问题是即使您 意思是 db.test.find({"a.2": null})query based on the index of 2 is null 这并不是它的实际含义。这意味着 either 索引 2 为 null 或者该对象的字段名称 2 为 null。在数组查询中,我们进入数组(也就是说a:2 应该匹配值2,但也可以匹配任何具有元素2 的数组。这里匹配器落入“我正在匹配子字段2 但这是一个数组,因此我应该检查数组的每个元素,看看它的字段名是2,值是null

这是查询语言中的一个不幸的歧义,它使得响应在某些情况下并不真正不正确,并且直到使用允许您明确指定您正在查询 only 数组的语法来增强该语言位置2 或仅用于字段名称2 查询a.2 结合null 语义将给出您看到的结果。

【讨论】:

  • 完全有道理,只是也尝试过...甚至没有意识到我可以拥有一个带有数字字段的文档?。感谢您解释查询引擎在幕后所做的事情! ?
  • 我们需要添加按位置查询的语法和按名称查询的语法(恰好是数字),但以一种不会向后中断的方式 - 这就是为什么它不是一个简单或短期的修复:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-14
  • 1970-01-01
  • 2012-02-14
  • 2015-12-08
  • 1970-01-01
  • 2018-09-28
相关资源
最近更新 更多