【问题标题】:How does MongoDB match a document without a property with a null queryMongoDB如何将没有属性的文档与空查询匹配
【发布时间】:2015-03-04 12:36:57
【问题描述】:

我有用户控制器,我写了以下带有条件的查找查询

$userData = $this->User->find('first', array('conditions'=>array('id'=>null)));

如果我使用id=null 条件编写查找查询,那么它也会从数据库返回第一条记录。

我预计没有任何记录 because 条件为假,但它写入了第一条记录。

我的问题是为什么记录是从数据库返回的,这背后的逻辑是什么?

生成的 MongoDB 查询

db.users.find( {"id":null}, [] ).sort( [] ).limit( 1 ).skip( 0 ).hint( [] );

更新

如果我使用有效的user_id 编写以下查询,那么它会返回记录。

$userData = $this->User->find('first', array('conditions'=>array('id'=>"54c72b984a1bfeb420324670")));

【问题讨论】:

  • 投反对票的人先了解我的问题,然后才能投反对票。
  • 生成的 SQL 是什么?
  • @AgRizzo 使用生成的查询检查更新的问题。
  • 您能向我们展示您不希望退回的退回文件吗?
  • 人们要问的是在字段“id”不为空的情况下返回什么文档?我怀疑这只是一个错字,而您的意思只是"_id": null。如果文档中没有实际的“id”字段,它仍然是有效的查询。

标签: php mongodb cakephp mongodb-query


【解决方案1】:

要给出解释,您需要考虑这里实际发生的情况。以这些文件为例:

{ "b": "a" },
{ "b": "a", "c": "d" }

如果你基本上形成这样的查询:

db.collection.find({ "c": "d" })

然后按预期得到第二个文档。

{ "b": "a", "c": "d" }

但如果您在同一字段上查询null

db.collection.find({ "c": null })

你会得到第一个响应文件:

{ "b": "a" },

原因是因为条件“为真”。文档中不存在任何字段,因此 MongoDB 会考虑针对 null 值的任何测试来证明该字段不存在的情况。如果该字段确实存在但不包含 null 的值,那么它将不符合该条件并且不会被返回。

因此,当您询问文档中不存在的字段值时,内部评估是字段“值”实际上是 null

【讨论】:

  • db.collection.find({ "d": null })db.collection.find({ "c": null }) 的输出是什么,其中d 不存在且c 存在但不包含null 值?
  • 答案就是这样。 "d": null 将返回该字段不存在的每个文档。所以这个例子中的所有文件。 "c": null 示例已在答案中。
  • 如果我写db.collection.find({ "c": null }),它将返回c 不存在于field 中的所有记录。正如你所说的第一个文件,但它返回所有文件。
  • @Sadikhasan “我的两个文档示例中的第一个文档”。关键是,如果您在文档中不存在的字段上查询null 值,那么所有 文档不包含该字段或“确实包含”该字段但实际存在的值返回。
  • 我明白了。感谢您的帮助并给予您宝贵的时间进行解释。
【解决方案2】:

首先,您的索引需要稀疏才能包含 NULL 值。见http://docs.mongodb.org/manual/core/index-sparse/#index-type-sparse

然后您生成的查询需要查找 BSON 类型 10,即仅 NULL,而不是 NULL。

例如:

db.users.find( { id : { $type: 10 } }, []).sort([]).limit(1).skip(0).hint [] )

如果没有这些设置,您的查询将正确找到第一条为 NULL 或不为 NULL 的记录。

【讨论】:

  • 索引需要稀疏,以便省略缺失值的文档;具有null 字段值的文档包含在稀疏和非稀疏索引中。此外,在 >= 2.6 版本中,a 上的稀疏索引不会用于像 { "a" : null } 这样可能会忽略结果的搜索。
猜你喜欢
  • 2019-05-06
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 2017-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-05
相关资源
最近更新 更多