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

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

{
  'sent_at': Date( 1336776254000 )
}

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

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

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

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

【问题讨论】:

    标签: mongodb null mongodb-query exists


    【解决方案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();
                

                【讨论】:

                  猜你喜欢
                  • 2013-10-20
                  • 1970-01-01
                  • 2020-08-21
                  • 1970-01-01
                  • 2014-12-04
                  相关资源
                  最近更新 更多