MongoDB:如何查询字段为空或未设置的记录?

Posted

技术标签:

【中文标题】MongoDB:如何查询字段为空或未设置的记录?【英文标题】:MongoDB: How to query for records where field is null or not set? 【发布时间】:2012-05-14 21:47:54 【问题描述】:

我有一个Email 文档,其中有一个sent_at 日期字段:


  'sent_at': Date( 1336776254000 )

如果此Email 尚未发送,则sent_at 字段为空或不存在。

我需要获取所有已发送/未发送 Emails 的计数。我一直在试图找出查询这些信息的正确方法。我认为这是获取发送计数的正确方法:

db.emails.count(sent_at: $ne: null)

但是我应该如何计算未发送的数量?

【问题讨论】:

【参考方案1】:

如果 sent_at 字段在未设置时不存在,则:

db.emails.count(sent_at: $exists: false)

如果它存在并且为空,或者根本不存在:

db.emails.count(sent_at: null)

如果它在那里并且为空:

db.emails.count(sent_at:  $type: 10 )

MongoDB 手册的Query for Null or Missing Fields 部分描述了如何查询空值和缺失值。

等式过滤器

item : null 查询匹配包含值为 null 的 item 字段的文档不包含 item 字段的文档。

db.inventory.find(  item: null  )

存在性检查

以下示例查询不包含字段的文档。

item : $exists: false 查询匹配不包含 item 字段的文档:

db.inventory.find(  item :  $exists: false   )

类型检查

item : $type: 10 查询 匹配包含item 字段且值为null 的文档;即项目字段的值为BSON TypeNull(类型号10):

db.inventory.find(  item :  $type: 10   )

【讨论】:

现在这是一个完整的答案。简直太棒了!谢谢【参考方案2】:

如果您只想计算定义为 nullsent_at 的文档(不要计算未设置 sent_at 的文档):

db.emails.count(sent_at:  $type: 10 )

【讨论】:

谢谢。在检查字段是否存在但设置为 null 时,这非常有用。 赞成,因为当使用find 和普通null 时,它会将0.0 之类的值解释为null,而这个解决方案避免了这种情况【参考方案3】:

用途:

db.emails.count(sent_at: null)

计算所有 sent_at 属性为 null 或未设置的电子邮件。 上面的查询与下面的相同。

db.emails.count($or: [
  sent_at: $exists: false,
  sent_at: null
])

【讨论】:

【参考方案4】:

看来你可以只做单行:

 "sent_at": null 

【讨论】:

【参考方案5】:

以上所有答案都令人惊叹且正确。只想对使用$type的答案添加一项改进。

Starting with MongoDB 3.2,您可以避免使用10(因为硬编码文字会降低代码的可读性),而可以简单地使用字符串别名,即"null"。所以总结一下-

1。如果您想选择存在sent_at 且值为null 的记录

db.emails.count(sent_at:  $type: 'null' );

// or
// This reduces the code readability as your peer might not know
// that what is the meaning of value 10
db.emails.count(sent_at:  $type: 10 );

2。如果您想选择 sent_at: nullsent_at 不存在的记录

// This will ensure both the conditions
db.emails.count( sent_at: null )

3。如果您只想要sent_at 不存在的记录

db.emails.count(sent_at:  $exists: false );

4。如果您只想选择sent_at,该字段存在并且可能具有任何值

db.emails.count(sent_at:  $exists: true );

请记住,这将拉取emails 的任何具有任何值的文档,包括null0''false

【讨论】:

【参考方案6】:

你也可以试试这个:

db.emails.find($and:[sent_at:$exists:true,'sent_at':null]).count()

【讨论】:

【参考方案7】:

您可以使用 $in 运算符来检查这两种情况

db.emails.find("sent_at": $in:[null,""]).count()

【讨论】:

【参考方案8】:

如果需要在同一个文档中检查属性和值的存在是否为空-

db.emails.count($or: [
  sent_at: $exists: false,
  sent_at: null
]) 

以上可以在单行查询中完成,这将花费更少的时间-

db.emails.count($or: [ sent_at: nil ])

因为nil 将获取文档,如果键 doesn't exist 除了值之外也是 null。Better to have a glance on source 它节省了我的时间。

注意:在较新版本的 mongodb 中使用 nil 而不是 null

【讨论】:

【参考方案9】:
db.employe.find( $and:[ "dept": $exists:false , "empno":  $in:[101,102]   ] ).count();

【讨论】:

以上是关于MongoDB:如何查询字段为空或未设置的记录?的主要内容,如果未能解决你的问题,请参考以下文章

VBA DAO.Recordset 在尝试关闭它时为空或未设置 - 但我事先检查它是不是为空

如何检查数据读取器是不是为空或为空

在查询SQL语句中为空或不为空怎么写

IE:无法获取属性“clientWidth”的值:对象为空或未定义

当第一个属性为空或未定义时如何使用 ES6 对象解构默认为另一个属性

对象可能为空或未定义 [重复]