我想执行以下查询:

db.mycollection.find(HAS IMAGE URL)

正确的语法应该是什么?


查询将是

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

它将返回所有具有“IMAGE URL”作为密钥的文档...........

这将返回所有带有“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})

在pymongo中,你可以使用:

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

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

另一种没有提到的替代方法是使用稀疏索引(仅当字段中有内容时,索引中的条目才存在),但对某些人来说可能是更有效的选择(不适用NULL条目)。下面是一个示例数据集:

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),因此请仅在适当的时候使用。

db.collection_name.find({"filed_name":{$exists:true}});

获取包含此filed_name的文档,即使它是空的。

警告

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"})

分享给未来的读者。

这个查询为我们工作(查询从MongoDB compass执行):

{
  "fieldName": {
    "$nin": [
      "",
      null
    ]
  }
}
db.<collectionName>.find({"IMAGE URL":{"$exists":"true"}, "IMAGE URL": {$ne: null}})

有一句话是最好的:

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

在这里,

我的收藏:放置你想要的收藏名称

Fieldname:放置你想要的字段名

解释:

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

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

所以在你提供的情况下,下面的查询将返回所有imageurl字段存在且非空值的文档:

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

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

您可以执行以下操作。

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

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

{ 'column_name': { $exists: true } }

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

下图为示例快照: