Mongoで「is not null」を照会するにはどうすればよいですか?


回答:


812

これにより、「IMAGE URL」というキーを持つすべてのドキュメントが返されますが、null値が残っている可能性があります。

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

これは、「画像のURL」と呼ばれるキーの両方ですべての文書を返しますし、 null以外の値。

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

これにより、3つのドキュメントすべてが返されます。

db.test.find();

これにより、最初と2番目のドキュメントのみが返されます。

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

これは最初のドキュメントのみを返します:

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

これにより、2番目と3番目のドキュメントのみが返されます。

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

13
ドキュメントによると$ne 、フィールドを含まないドキュメントが含まれます。回答を投稿してからこれは変わりましたか?docs.mongodb.org/manual/reference/operator/query/ne
Andrew Mao

2
私はそれが変わったとは思わない。$ neをチェックすると、フィールドを含まないドキュメントを含むすべてのドキュメントで値がチェックされますが、フィールドの値がまだnullであるため、$ ne:nullはフィールドを含まないドキュメントと一致しません。フィールドがそのドキュメントに存在しない場合でも。
Tim Gautier

2
2番目のドキュメントとどのように一致させるのですか?
BT

1
@Riverこれを3年前に書いたときにチェックしましたが、念のため、Mongoをインストールしてもう一度試してみました。それでも同じように機能し、答えは正しいです。最後から2番目のクエリは、最初のドキュメントのみを返します。
Tim Gautier 2017年

1
与えられた例は、これの使い方を本当に理解しやすくします。:-)
Eric Dela Cruz

92

ワンライナーは最高です:

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

ここに、

mycollection:希望するコレクション名を配置します

fieldname:希望するフィールド名を配置します

説明:

$ exists:trueの場合、$ existsはフィールドを含むドキュメント(フィールド値がnullのドキュメントを含む)と一致します。がfalseの場合、クエリはフィールドを含まないドキュメントのみを返します。

$ neは、フィールドの値が指定された値と等しくないドキュメントを選択します。これには、フィールドを含まないドキュメントも含まれます。

したがって、提供されたケースでは、imageurlフィールドが存在し、null値を持たないすべてのドキュメントを返す次のクエリ:

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

11
$exists: true冗長です、$ne: null十分です。
スタニスラフ

これが最良の答えです。値も$exists: true返しnullます。両方がなければならない$exists: trueとします$ne: null。冗長ではありません。
Ismail Kattakath

47

pymongoでは、以下を使用できます。

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

pymongoはmongoの「null」をpythonの「None」として表すためです。


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

nullであっても、このfiled_nameを含むドキュメントをフェッチします。

私の命題:

db.collection_name.find({"field_name":{$type:2}}) //type:2 == String

必須属性のタイプを確認できます。フィールドのタイプを確認しているため、フィールドの名前に値が含まれているすべてのドキュメントが返されます。それ以外の場合は、タイプ条件が一致しないため、何も返されません。

Nb:field_nameに ""を意味する空の文字列がある場合、それが返されます。これは、

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

追加の検証:

さて、まだ完成していません。追加の条件が必要です。

db.collection_name.
find({ "field_name":{$type:2},$where:"this.field_name.length >0"})

または

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

参照



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

これは有効なJsonドキュメントですか?クエリドキュメント内の同じ名前の2つのプロパティ。あなたがしなければならなかった場合、どのようにそれをメモリに構築するのかわかりません。
BrentR 2018年

4

理想的なケースでは、null""、または(フィールドがレコードに存在しない)の 3つのすべてをテストしたいとします

次のことができます。

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

3

言及されていないが、一部の(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" }
{  }
{  }

OK、それで、何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()はこの方法では使用できないため(たとえば、4ではなく6が返されるため)、適切な場合にのみ使用してください。


テキストフィールドは常にスパースインデックスです。明示的に指定する必要はありません。ちょうど私の2セント。
alianos- 2017

3

mongo compassで列の存在を確認する最も簡単な方法は次のとおりです。

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

1
これの問題は、フィールドが本当は永続化されなかったと想定していることですが、OPは存在する可能性があるが明示的にnullに設定できることを(見出しから)示しているようです。
Carighan

-10

クエリは

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

「イメージURL」をキーとして持つすべてのドキュメントを返します...........


1
@kiliancそうではありません。$ existsはnull値もキャプチャします。docs.mongodb.org/manual/reference/operator/query/exists
dorvakを

@dorvak正確に、それが問題のユースケースを満たさない理由です。
kilianc 2016

これ答えは間違っている$existsキーをチェック"IMAGE URL"して、それの値を(考慮しないnull)としますと、文書を返します"IMAGE URL" : null
デビッドハリリ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.