在我看来,当你创建一个Mongo文档,并有一个字段{key: value}
,有时是不会有一个值,你有两个选择:
1.写入{key: null}
,即在字段中写入空值
1.根本不要将密钥存储在该文档中
这两个选项都很容易查询,在一个选项中查询{key : null}
,在另一个选项中查询{key : {$exists : false}}
。
我实在想不出这两个选项之间有什么不同,它们在应用程序场景中会有什么影响(除了选项2的存储空间稍微少一点)。
有没有人能告诉我,有没有什么理由让人更喜欢这两种方法中的任何一种,为什么?
编辑
在问完这个问题后,我也想到了索引在这两种情况下的行为可能不同,即可以为选项2创建稀疏索引。
5条答案
按热度按时间ujv3wf0j1#
事实上,你还有第三种可能性:
key: ""
(空值)而且你忘记了一个关于null值的特性。
key: null
上的查询将检索所有key为null**或key不存在的文档。当
$exists:false
上的查询将只检索字段键不存在的文档时。要返回到您的确切问题,这取决于您的查询和数据表示的内容。如果您需要保留该字段,例如,用户设置了一个值,然后又取消设置它,您应该将该字段保留为null或空。如果不需要,您可以删除该字段。
agxfikkp2#
请注意,由于MongoDB不使用字段名字典压缩,
field:null
会消耗磁盘空间和RAM,而根本不存储键则不会消耗资源。ggazkfy83#
它实际上归结为:
我个人选择了存储空键。这使得它更容易集成到我的应用程序中。我使用PHP与活动记录和使用空值使我的生活更容易,因为我不必把压力的字段依赖于应用程序。我也不需要做任何复杂的代码来处理魔术设置不存在的变量。
我个人不会存储像
""
这样的空值,因为如果你不小心的话,你可能会有两个空值null
和""
,然后你会有一个偶然的时间来查询特定的值。所以我个人更喜欢null
作为空值。至于空间和索引:这取决于有多少行可能没有这个列,但我怀疑你是否真的注意到索引大小的增加,因为一些额外的文档中有null。我的意思是存储的差异是很小的,特别是如果相应的键名也很小。这也适用于大型设置。
坦率地说,我不确定
$exists
和null
之间的索引用法,但是null
可能是一个更标准化的方法,通过它来查询存在性,因为请记住MongoDB是无模式的,这意味着您不需要在文档中拥有该字段,这又会产生两个空值:不存在和null
。所以最好选择其中之一。我选择
null
。s71maibg4#
您可能需要考虑的另一点是在使用OGM工具(如Hibernate OGM)时。
如果您使用的是Java,Hibernate OGM支持JPA标准。因此,如果您可以编写JPQL查询,那么,如果您希望切换到OGM工具支持的备用NoSQL数据存储库,理论上会很容易。
JPA没有为Mongo中的$exists定义一个等价的属性。所以如果你的集合中有可选的属性,那么你就不能为它写一个合适的JPQL。在这种情况下,如果属性的值存储为NULL,那么仍然可以写一个有效的JPQL查询,如下所示。
6qqygrtg5#
我认为在磁盘空间方面的差异是可以忽略不计的。如果你需要在这个字段上创建索引,那么考虑部分索引。
用
{ partialFilterExpression: { key: { $exists: true } } }
表示的指数可以比普通指数小得多。还应注意,查询的外观不同,见如下值:
或者用
db.collection.find()
表示: