W jaki sposób pytasz o „nie jest zerowy” w Mongo?

Odpowiedzi:

812

Spowoduje to zwrócenie wszystkich dokumentów z kluczem o nazwie „IMAGE URL”, ale nadal mogą mieć wartość zerową.

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

Spowoduje to zwrócenie wszystkich dokumentów z kluczem o nazwie „IMAGE URL” i wartością inną niż null.

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

Ponadto, zgodnie z dokumentami, $ istnieje obecnie nie może używać indeksu, ale $ ne może.

Edycja: dodanie kilku przykładów ze względu na zainteresowanie tą odpowiedzią

Biorąc pod uwagę te wkładki:

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

Spowoduje to zwrócenie wszystkich trzech dokumentów:

db.test.find();

Zwróci tylko pierwszy i drugi dokument:

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

Zwróci tylko pierwszy dokument:

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

Zwróci tylko drugi i trzeci dokument:

db.test.find({"check":null})
Tim Gautier
źródło
12
Według dokumentów, $ne obejmuje dokumenty, które nie zawierają pola . Czy zmieniło się to od czasu opublikowania odpowiedzi? docs.mongodb.org/manual/reference/operator/query/ne
Andrew Mao
2
Nie wierzę, że to się zmieniło. Podczas sprawdzania $ ne wartość jest sprawdzana we wszystkich dokumentach, łącznie z tymi, które nie zawierają pola, ale $ ne: null nadal nie będzie pasować do dokumentu, który nie zawiera pola, ponieważ wartość pola jest wciąż pusta, nawet jeśli pole nie istnieje w tym dokumencie.
Tim Gautier
2
Jak dopasujesz drugi dokument?
BT
1
@ Rzeka Sprawdziłem, kiedy napisałem to 3 lata temu i, aby się upewnić, właśnie zainstalowałem Mongo i wypróbowałem go ponownie. Nadal działa w ten sam sposób, odpowiedź jest prawidłowa. Przedostatnie zapytanie zwraca tylko pierwszy dokument.
Tim Gautier,
1
Podane przykłady sprawiają, że naprawdę zrozumiałe jest, jak z tego korzystać. :-)
Eric Dela Cruz
92

Jedna wkładka jest najlepsza:

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

Tutaj,

mycollection : umieść żądaną nazwę kolekcji

nazwa_pola : umieść swoją pożądaną nazwę pola

Wyjaśnienie:

$ istnieje : Kiedy jest prawdziwe, $ istnieje pasuje do dokumentów zawierających pole, w tym dokumentów, w których wartość pola jest równa null. Jeśli ma wartość false, zapytanie zwraca tylko dokumenty, które nie zawierają pola.

$ ne wybiera dokumenty, w których wartość pola nie jest równa podanej wartości. Obejmuje to dokumenty, które nie zawierają pola.

Tak więc w podanym przypadku istnieje zapytanie zwracające wszystkie dokumenty z polem imageurl, które nie mają wartości zerowej:

db.mycollection.find({ 'imageurl' : { $exists: true, $ne: null } });
Amitesh
źródło
11
$exists: truejest zbędny, $ne: nullwystarczy.
Stanislav Karakhanov
To powinna być najlepsza odpowiedź. $exists: truezwraca nullrównież wartości. Musi być jedno $exists: truei drugie $ne: null. To NIE jest zbędne.
Ismail Kattakath
47

W pymongo możesz użyć:

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

Ponieważ pymongo reprezentuje mongo „null” jako python „None”.

użytkownik2293072
źródło
18
db.collection_name.find({"filed_name":{$exists:true}});

pobierz dokumenty zawierające tę nazwę pliku, nawet jeśli jest ona pusta.

Moja propozycja:

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

Możesz sprawdzić typ wymaganego atrybutu, zwróci on wszystkie dokumenty, których kwerenda nazwa_pola zawiera wartość, ponieważ sprawdzasz typ pliku w innym przypadku, jeśli jest pusty, warunek typu nie pasuje, więc nic nie zostanie zwrócone.

Uwaga : jeśli nazwa_pola ma pusty ciąg znaków, co oznacza „”, zostanie zwrócona. To samo zachowanie

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

Dodatkowa walidacja:

Okej, więc jeszcze nie skończyliśmy, potrzebujemy dodatkowego warunku.

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

LUB

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

Odniesienie

Farouk El kholy
źródło
14

Udostępnianie dla przyszłych czytelników.

To zapytanie działało dla nas (zapytanie wykonane z kompasu MongoDB ):

{
  "fieldName": {
    "$nin": [
      "",
      null
    ]
  }
}
Mohammed Zameer
źródło
1
{$ istnieje: prawda, $ ne: null} nie pokazał poprawnego wyniku. Twoje zapytanie działa dobrze
Oleksandr Buchek
1
Uważaj, nin $ często nie optymalizuje w stosunku do indeksów
Wheezil
4
db.<collectionName>.find({"IMAGE URL":{"$exists":"true"}, "IMAGE URL": {$ne: null}})
Berhanu Tarekegn
źródło
Czy to ważny dokument Jsona? Dwie właściwości o tej samej nazwie w dokumencie zapytania. Nie jestem pewien, jak zbudowałbyś to w pamięci, gdybyś musiał.
BrentR
4

W idealnym przypadku chciałbyś przetestować wszystkie trzy wartości , null , „” lub puste (pole nie istnieje w rekordzie)

Możesz wykonać następujące czynności.

db.users.find({$and: [{"name" : {$nin: ["", null]}}, {"name" : {$exists: true}}]})
Ankit Marothi
źródło
3

Alternatywą, o której nie wspomniano, ale która może być bardziej wydajną opcją dla niektórych (nie będzie działać z pozycjami NULL), jest użycie indeksu rzadkiego (wpisy w indeksie istnieją tylko wtedy, gdy jest coś w polu). Oto przykładowy zestaw danych:

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 }

Teraz utwórz indeks rzadki w polu imageUrl:

db.foo.ensureIndex( { "imageUrl": 1 }, { sparse: true } )
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

Teraz zawsze istnieje szansa (a zwłaszcza przy małym zestawie danych, takim jak moja próbka), że zamiast używać indeksu, MongoDB użyje skanowania tabeli, nawet w przypadku potencjalnie objętego zapytania indeksu. Jak się okazuje, daje mi to łatwy sposób zilustrowania różnicy tutaj:

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, więc dodatkowe dokumenty bez imageUrlsą zwracane, tylko puste, a nie to, co chcieliśmy. Aby potwierdzić, wyjaśnij:

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
}

Tak, a więc jest BasicCursorrówny skanowi tabeli, nie używał indeksu. Zmuśmy zapytanie do użycia naszego rzadkiego indeksu z 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" }

I jest wynik, którego szukaliśmy - zwracane są tylko dokumenty z wypełnionym polem. To również używa tylko indeksu (tzn. Jest to zapytanie indeksu objętego zakresem), więc tylko indeks musi być w pamięci, aby zwrócić wyniki.

Jest to wyspecjalizowany przypadek użycia i nie można go ogólnie używać (zobacz inne odpowiedzi na temat tych opcji). W szczególności należy zauważyć, że w obecnej sytuacji nie można używać count()w ten sposób (w moim przykładzie zwróci 6, a nie 4), więc proszę używać tylko w razie potrzeby.

Adam Comerford
źródło
pola tekstowe są zawsze rzadkimi indeksami, nie musisz tego wyraźnie określać. tylko moje 2 centy.
alianos-
3

Najprostszym sposobem sprawdzenia istnienia kolumny w kompasie mongo jest:

{ 'column_name': { $exists: true } }
Taha Hamedani
źródło
1
Problem polega na tym, że zakłada, że ​​pole rzeczywiście nigdy nie zostało utrzymane, ale wydaje się, że PO wskazuje (z nagłówka), że może istnieć, ale należy wyraźnie ustawić na zero.
Carighan
-10

Zapytanie będzie

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

zwróci wszystkie dokumenty posiadające „IMAGE URL” jako klucz ...........

Sagar Varpe
źródło
1
@kilianc To nieprawda. $ istnieje również przechwytuje wartości zerowe. Zobacz docs.mongodb.org/manual/reference/operator/query/exists
dorvak
@dorvak dokładnie, dlatego nie spełnia przypadku użycia w pytaniu.
kilianc
Ta odpowiedź jest błędna, ponieważ $existssprawdza klucz "IMAGE URL"i nie bierze pod uwagę jego wartość ( null) i będzie zwrócić dokument "IMAGE URL" : null.
David Hariri