web-dev-qa-db-ja.com

どのようにしてMongoで "is not null"を検索しますか?

以下のクエリを実行したいです。

db.mycollection.find(HAS IMAGE URL)

正しい構文は何ですか?

311
TIMEX

これは "IMAGE URL"と呼ばれるキーを持つすべてのドキュメントを返しますが、それらはまだnull値を持つ可能性があります。

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

これは、 "IMAGE 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();

これは1番目と2番目の文書だけを返します。

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

これは最初の文書だけを返します。

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

これは2番目と3番目の文書だけを返します。

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

Pymongoではあなたが使うことができます:

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

Pymongoはmongoの "null"をpythonの "None"として表しているからです。

40
user2293072

一つのライナーが最高です:

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

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

nullの場合でも、このfiled_nameを含む文書を取り出します。

私の命題:

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

必須の属性の型をチェックすることができます。フィールドの型がnullの場合は型条件が一致しないため、何も返されないため、フィールド名の型をチェックしているためすべてのドキュメントが返されます。

N.b:field_nameに ""を意味する空の文字列が含まれている場合はそれが返されます。db.collection_name.find({"filed_name":{$ne:null}});の場合と同じ動作です。

追加の検証:

わかりました、それで私達はまだ終わっていませんまだ追加の条件が必要です。

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

OR

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

すべての型に関する参照: https://docs.mongodb.com/manual/reference/operator/query/type /#op._S_type

14
Farouk El kholy

将来の読者のための共有.

このクエリは役に立ちました( MongoDB compass から実行されたクエリ)。

{
  "fieldName": {
    "$nin": [
      "",
      null
    ]
  }
}
11
student

言及されていないが、それはいくつかのより効率的なオプションかもしれません(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
Adam Comerford
db.<collectionName>.find({"IMAGE URL":{"$exists":"true"}, "IMAGE URL": {$ne: null}})
2