MongoDB 未正确查询数组中给定位置的“null”
MongoDB not querying `null` within a array at a given posision correctly
我很难理解为什么在查询中处理空值和数组索引时 mongodb 会发生以下情况。
假设我们有以下内容:
> db.test.find()
{ "_id" : ObjectId("5852da24507d8c27f4e3c357"), "item" : null }
{ "_id" : ObjectId("5852da2d507d8c27f4e3c358"), "item" : { "something" : true } }
{ "_id" : ObjectId("5852da33507d8c27f4e3c359") }
当我尝试查找 null 项目时,我得到 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 为 null 进行查询,我们仍然会返回所有文档:
> 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 中处理数组和空值的错误吗?
问题是,即使您 的意思是 使 db.test.find({"a.2": null})
成为 query based on the index of 2 is null
,但这并不是它实际的意思。它的意思是要么 2 的索引为空,要么对象的某个字段名称2
为空。在数组查询中,我们进入数组(所以说 a:2
应该匹配值 2
但也匹配任何具有元素 2
的数组。这里匹配器落入“我正在匹配子字段 2
但这是一个数组,因此我应该检查数组的每个元素以查看它是否是字段名称 2
、值 null
.
这是查询语言中的一个不幸的歧义,它使得响应在某些情况下并不是真的不正确,直到语言被增强的语法允许您明确指定您正在查询 only 用于数组位置 2
或仅用于字段名称 2
查询 a.2
结合 null
语义将给出您看到的结果。
我很难理解为什么在查询中处理空值和数组索引时 mongodb 会发生以下情况。
假设我们有以下内容:
> db.test.find()
{ "_id" : ObjectId("5852da24507d8c27f4e3c357"), "item" : null }
{ "_id" : ObjectId("5852da2d507d8c27f4e3c358"), "item" : { "something" : true } }
{ "_id" : ObjectId("5852da33507d8c27f4e3c359") }
当我尝试查找 null 项目时,我得到 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 为 null 进行查询,我们仍然会返回所有文档:
> 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 中处理数组和空值的错误吗?
问题是,即使您 的意思是 使 db.test.find({"a.2": null})
成为 query based on the index of 2 is null
,但这并不是它实际的意思。它的意思是要么 2 的索引为空,要么对象的某个字段名称2
为空。在数组查询中,我们进入数组(所以说 a:2
应该匹配值 2
但也匹配任何具有元素 2
的数组。这里匹配器落入“我正在匹配子字段 2
但这是一个数组,因此我应该检查数组的每个元素以查看它是否是字段名称 2
、值 null
.
这是查询语言中的一个不幸的歧义,它使得响应在某些情况下并不是真的不正确,直到语言被增强的语法允许您明确指定您正在查询 only 用于数组位置 2
或仅用于字段名称 2
查询 a.2
结合 null
语义将给出您看到的结果。