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

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

{
'sent_at': Date( 1336776254000 )
}

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

我需要得到所有发送/未发送 Emails的计数。我被困在试图找出正确的方法来查询这些信息。我认为这是获得发射次数的正确方法:

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

但是我应该怎样计算那些没有被发送的人的数量呢?

170753 次浏览

如果没有设置 sent_at字段,那么:

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

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

db.emails.count({sent_at: null})

如果它存在并且无效:

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

MongoDB 手册的 空字段或缺少字段的查询部分描述了如何查询空值和缺失值。

相等过滤器

{ item : null }查询匹配包含值为 null 或者但不包含 item字段的项字段的文档。

db.inventory.find( { item: null } )

生存检查

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

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

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

类型检查

{ item : { $type: 10 } }查询匹配包含值为 nullitem字段的 只有文档; 也就是说,项目字段的值为 BSON 类型 Null(类型编号为 10) :

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

看来你只需要说一句话:

{ "sent_at": null }

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

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

用途:

db.emails.count({sent_at: null})

它计算其 send _ at 属性为 null 或未设置的所有电子邮件的数量。 上面的查询与下面的查询相同。

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

你也可以试试这个:

db.emails.find($and:[{sent_at:{$exists:true},'sent_at':null}]).count()
db.employe.find({ $and:[ {"dept":{ $exists:false }, "empno": { $in:[101,102] } } ] }).count();

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

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

以上所有的答案都是令人惊讶的,也是正确的。只是想增加一个改进的答案是使用 $type

从 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

如果需要,则检查同一文档中的属性和值是否等于 null

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

以上可以在一个单行查询,这将采取较少的时间作为-

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

因为如果键 doesn't exist除了值之外还是 null,那么 nil将获取文档。
最好看一眼它拯救了我的一天。

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