61

在我看来,当您创建一个 Mongo 文档并且有一个{key: value}有时不会有值的字段时,您有两个选择:

  1. 写入{key: null}即在字段中写入空值
  2. 根本不要将密钥存储在该文档中

这两个选项都很容易查询,一个是您查询,{key : null}另一个是您查询{key : {$exists : false}}

我真的想不出这两个选项之间的任何差异会对应用程序场景产生任何影响(除了选项 2 的存储量略少)。

谁能告诉我是否有任何理由更喜欢这两种方法中的任何一种,为什么?

编辑

在问了这个问题之后,我还想到索引在这两种情况下的行为可能不同,即可以为选项 2 创建一个稀疏索引。

4

4 回答 4

42

确实,您还有第三种可能性:( key: ""空值)

而且您忘记了有关空值的特殊性。查询 key: null将检索您所有 key 为 nullkey 不存在的文档。

当查询$exists:false将仅检索字段键不存在的文档时。

回到您的确切问题,这取决于您的查询和数据代表的内容。如果您需要保留它,例如,用户设置了一个值然后取消设置它,您应该将该字段保留为 null 或空。如果您不需要,您可以删除此字段。

于 2012-09-13T10:28:30.400 回答
19

请注意,由于 MongoDB 不使用字段名字典压缩,field:null因此会消耗磁盘空间和 RAM,而根本不存储 key 不会消耗资源。

于 2012-09-13T19:13:33.380 回答
9

它真的归结为:

  • 你的场景
  • 您的查询方式
  • 您的索引需求
  • 你的语言

我个人选择存储空键。它使集成到我的应用程序中变得更加容易。我将 PHP 与 Active Record 一起使用,并且 uisng 空值使我的生活变得更轻松,因为我不必将字段依赖的压力放在应用程序上。此外,我不需要编写任何复杂的代码来处理设置不存在变量的魔法。

我个人不会存储一个空值,""因为如果你不小心,你可能有两个空值null""然后你会有一个偶然的时间专门查询。所以我个人更喜欢null空值。

至于空间和索引:这取决于有多少行可能没有此列,但我怀疑您是否真的会注意到索引大小会由于一些带有 null in 的额外文档而增加。我的意思是存储的差异是微小的,特别是如果相应的键名也很小。这也适用于大型设置。

坦率地说,我不确定之间的索引使用情况$existsnull但是null可能是一种更标准化的方法来查询存在性,因为请记住 MongoDB 是无模式的,这意味着您不需要在文档中包含该字段,该字段再次产生两个空值:不存在和null。所以最好选择其中一个。

我选择null

于 2012-09-13T22:17:31.707 回答
2

您可能要考虑的另一点是当您使用诸如 Hibernate OGM 之类的 OGM 工具时。

如果您使用 Java,Hibernate OGM 支持 JPA 标准。因此,如果您可以编写 JPQL 查询,如果您想切换到 OGM 工具支持的备用 NoSQL 数据存储,理论上会很容易。

JPA 没有在 Mongo 中定义 $exists 的等价物。因此,如果您的集合中有可选属性,那么您无法为其编写适当的 JPQL。在这种情况下,如果属性的值存储为 NULL,那么仍​​然可以编写一个有效的 JPQL 查询,如下所示。

SELECT p FROM pppoe p where p.logout IS null;
于 2016-07-14T09:45:12.000 回答