您如何在 Mongo 中查询“不为空”?

Posted

技术标签:

【中文标题】您如何在 Mongo 中查询“不为空”?【英文标题】:How do you query for "is not null" in Mongo? 【发布时间】:2011-05-02 17:08:27 【问题描述】:

我想执行以下查询:

db.mycollection.find(HAS IMAGE URL)

正确的语法应该是什么?

【问题讨论】:

简答:查询 field : $ne : null 检查非空docs.mongodb.org/manual/reference/operator/query/ne 【参考方案1】:

这将返回所有带有一个名为“IMAGE URL”的键的文档,但它们可能仍然有一个空值。

db.mycollection.find("IMAGE URL":$exists:true);

这将返回所有具有名为“IMAGE URL”的键非空值的文档。

db.mycollection.find("IMAGE URL":$ne:null);

另外,根据文档,$exists 目前不能使用索引,但 $ne 可以。

编辑:由于对此答案感兴趣而添加了一些示例

鉴于这些插入:

db.test.insert("num":1, "check":"check value");
db.test.insert("num":2, "check":null);
db.test.insert("num":3);

这将返回所有三个文档:

db.test.find();

这将只返回第一个和第二个文档:

db.test.find("check":$exists:true);

这将只返回第一个文档:

db.test.find("check":$ne:null);

这将只返回第二个和第三个文档:

db.test.find("check":null)

【讨论】:

根据文档,$ne包括不包含该字段的文档。自从您发布答案以来,这种情况发生了变化吗? docs.mongodb.org/manual/reference/operator/query/ne 我不相信这已经改变了。检查 $ne 时,会在所有文档中检查该值,包括不包含该字段的文档,但 $ne:null 仍然不会匹配不包含该字段的文档,因为该字段的值仍然为 null,即使该字段在该文档中不存在。 如何匹配第二个文档? @River 我在 3 年前写这篇文章时检查过,为了确定,我刚刚安装了 Mongo 并再次尝试了它。它仍然以相同的方式工作,答案是正确的。倒数第二个查询仅返回第一个文档。 给出的例子让如何使用它变得非常容易理解。 :-)【参考方案2】:

一个班轮是最好的:

db.mycollection.find( 'fieldname' :  $exists: true, $ne: null  );

这里,

mycollection:放置您想要的收藏名称

fieldname:放置您想要的字段名称

说明:

$exists :当为真时,$exists 匹配包含该字段的文档,包括字段值为空的文档。如果为 false,则查询只返回不包含该字段的文档。

$ne 选择字段值不等于指定值的文档。这包括不包含该字段的文档。

因此,在您提供的情况下,以下查询将返回所有具有 imageurl 字段且不具有空值的文档:

db.mycollection.find( 'imageurl' :  $exists: true, $ne: null  );

【讨论】:

$exists: true 是多余的,$ne: null 就足够了。 这应该是最好的答案。 $exists: true 也返回 null 值。必须同时存在$exists: true$ne: null。这不是多余的。 @IsmailKattakath $ne: null 使 $exists: true — 由您自己解释!由于$exists: true 返回null 值,而$ne: null 过滤掉这些值,您只需要$ne: null【参考方案3】:

在 pymongo 中你可以使用:

db.mycollection.find("IMAGE URL":"$ne":None);

因为 pymongo 将 mongo "null" 表示为 python "None"。

【讨论】:

【参考方案4】:
db.collection_name.find("filed_name":$exists:true);

获取包含此字段名称的文档,即使它为空。

警告

db.collection_name.find("filed_name":$ne:null);

获取其 field_name 的值 $ne 为 null 但该值也可以是空字符串的文档。

我的建议:

db.collection_name.find( "field_name":$ne:null,$where:"this.field_name.length >0")

【讨论】:

【参考方案5】:

分享给未来的读者。

这个查询对我们有用(查询从MongoDB compass 执行):


  "fieldName": 
    "$nin": [
      "",
      null
    ]
  

【讨论】:

$exists: true, $ne: null 没有显示正确的结果。您的查询效果很好 小心,$nin 通常不会优化索引【参考方案6】:

在理想情况下,您希望测试所有三个 null""empty(记录中不存在字段)

您可以执行以下操作。

db.users.find($and: ["name" : $nin: ["", null], "name" : $exists: true])

【讨论】:

【参考方案7】:

在 mongo compass 中检查该列是否存在的最简单方法是:

 'column_name':  $exists: true  

【讨论】:

这个问题是它假设该字段确实从未持久化,但 OP 似乎(从标题中)表明它可能存在但明确设置为 null。【参考方案8】:

另一种没有被提及,但对某些人来说可能是更有效的选择(不适用于 NULL 条目)是使用sparse index(索引中的条目仅在索引中有内容时存在场地)。这是一个示例数据集:

db.foo.find()
 "_id" : ObjectId("544540b31b5cf91c4893eb94"), "imageUrl" : "http://example.com/foo.jpg" 
 "_id" : ObjectId("544540ba1b5cf91c4893eb95"), "imageUrl" : "http://example.com/bar.jpg" 
 "_id" : ObjectId("544540c51b5cf91c4893eb96"), "imageUrl" : "http://example.com/foo.png" 
 "_id" : ObjectId("544540c91b5cf91c4893eb97"), "imageUrl" : "http://example.com/bar.png" 
 "_id" : ObjectId("544540ed1b5cf91c4893eb98"), "otherField" : 1 
 "_id" : ObjectId("544540f11b5cf91c4893eb99"), "otherField" : 2 

现在,在 imageUrl 字段上创建稀疏索引:

db.foo.ensureIndex(  "imageUrl": 1 ,  sparse: true  )

    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1

现在,MongoDB 总是有机会(尤其是对于像我的示例这样的小数据集)而不是使用索引,而是使用表扫描,即使对于潜在的覆盖索引查询也是如此。事实证明,这给了我一个简单的方法来说明这里的区别:

db.foo.find(, _id : 0, imageUrl : 1)
 "imageUrl" : "http://example.com/foo.jpg" 
 "imageUrl" : "http://example.com/bar.jpg" 
 "imageUrl" : "http://example.com/foo.png" 
 "imageUrl" : "http://example.com/bar.png" 
  
  

好的,所以没有imageUrl 的额外文档将被返回,只是空的,不是我们想要的。只是为了确认原因,请解释一下:

db.foo.find(, _id : 0, imageUrl : 1).explain()

    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 6,
    "nscannedObjects" : 6,
    "nscanned" : 6,
    "nscannedObjectsAllPlans" : 6,
    "nscannedAllPlans" : 6,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "server" : "localhost:31100",
    "filterSet" : false

所以,是的,BasicCursor 等于表扫描,它没有使用索引。让我们强制查询使用带有hint() 的稀疏索引:

db.foo.find(, _id : 0, imageUrl : 1).hint(imageUrl : 1)
 "imageUrl" : "http://example.com/bar.jpg" 
 "imageUrl" : "http://example.com/bar.png" 
 "imageUrl" : "http://example.com/foo.jpg" 
 "imageUrl" : "http://example.com/foo.png" 

这就是我们正在寻找的结果 - 仅返回填充了该字段的文档。这也只使用了索引(即它是一个覆盖索引查询),所以只有索引需要在内存中才能返回结果。

这是一个专门的用例,不能普遍使用(有关这些选项,请参阅其他答案)。特别要注意的是,就目前情况而言,您不能以这种方式使用count()(对于我的示例,它将返回 6 而不是 4),因此请仅在适当的时候使用。

【讨论】:

文本字段总是稀疏索引,您不必明确指定。只是我的 2 美分。【参考方案9】:
db.<collectionName>.find("IMAGE URL":"$exists":"true", "IMAGE URL": $ne: null)

【讨论】:

这是一个有效的 Json 文档吗?查询文档中有两个同名的属性。如果必须的话,不确定如何在内存中构建它。【参考方案10】:

感谢您提供解决方案,我注意到在 MQL 中,有时 $ne:null 不起作用,我们需要使用语法 $ne:"" 即在上述示例的上下文中我们需要使用 db.mycollection。 find("IMAGE URL":"$ne":"") - 不知道为什么会这样,我已经在 MongoDB 论坛上发布了这个问题。

以下是截图示例:

enter image description here

【讨论】:

请考虑用文字而不是屏幕截图来发布您的答案。 meta.***.com/questions/303812/… 顺便看看数据类型docs.mongodb.com/manual/reference/bson-types 屏幕截图显示您在数据库中保存了空字符串。这些可能没有用,但它们也不是空的,所以它按预期工作。【参考方案11】:

查询将是

db.mycollection.find("IMAGE URL":"$exists":"true")

它将返回所有以“IMAGE URL”为键的文档......

【讨论】:

@kilianc 这不是真的。 $exists 也将捕获空值。见docs.mongodb.org/manual/reference/operator/query/exists @dorvak 确切地说,这就是为什么这不能满足问题中的用例。 这个答案是错误的,因为$exists 检查键 "IMAGE URL" 并且不考虑它的值 (null) 并且 返回带有 "IMAGE URL" : null 的文档.

以上是关于您如何在 Mongo 中查询“不为空”?的主要内容,如果未能解决你的问题,请参考以下文章

用PHP查询mongo数据时,条件是某个字段(A为数组)不为空,但是有的记录中并没有字段A,这个条件怎么写?

如何在mongodb聚合中检查子字段是不是存在且不为空?

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

如何匹配不为空+不为空?

如何在mysql中获取值不为null的列名

从组合框中过滤查询(为 Null 且不为空)