web-dev-qa-db-fra.com

Comment interrogez-vous le mot "is not null" dans Mongo?

Je voudrais exécuter une requête suivante:

db.mycollection.find(HAS IMAGE URL)

Quelle devrait être la syntaxe correcte?

328
TIMEX

Cela renverra tous les documents avec une clé appelée "URL IMAGE", mais ils peuvent toujours avoir une valeur nulle.

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

Cela renverra tous les documents avec une clé appelée "URL IMAGE" et une valeur non nulle.

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

De plus, selon la documentation, $ existe actuellement ne peut pas utiliser d'index, mais $ ne peut.

Edit: Ajout de quelques exemples en raison de l'intérêt pour cette réponse

Étant donné ces inserts:

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

Cela renverra les trois documents:

db.test.find();

Cela renverra les premier et deuxième documents uniquement:

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

Cela renverra le premier document uniquement:

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

Cela renverra les deuxième et troisième documents uniquement:

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

Un paquebot est le meilleur:

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

Ici,

mycollection: placez le nom de votre collection souhaitée

nom du champ: placez le nom de votre champ souhaité

Explication:

$ existe: Lorsque la valeur est true, $ existant correspond aux documents contenant le champ, y compris les documents pour lesquels la valeur du champ est null. Si la valeur est false, la requête renvoie uniquement les documents qui ne contiennent pas le champ.

$ ne sélectionne les documents pour lesquels la valeur du champ n'est pas égale à la valeur spécifiée. Cela inclut les documents qui ne contiennent pas le champ.

Donc, dans votre cas fourni, la requête suivante retournera tous les documents avec le champ imageurl existe et n’ayant pas de valeur NULL:

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

En pymongo, vous pouvez utiliser:

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

Parce que pymongo représente mongo "null" en tant que python "Aucun".

42
user2293072

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

récupère les documents contenant ce filededname même s'il est null.

Ma proposition:

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

Vous pouvez vérifier le type de l'attribut requis, il renverra tous les documents que son nom de champ interrogé contient une valeur car vous vérifiez le type du fichier, sinon s'il est nul, la condition de type ne correspond pas et rien ne sera renvoyé.

N.b : si le nom du champ contient une chaîne vide qui signifie "", elle sera renvoyée. Le comportement est identique pour db.collection_name.find({"filed_name":{$ne:null}});.

Validation supplémentaire:

Bon, alors nous n’avons pas encore fini, nous avons besoin d’une condition supplémentaire.

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

Référence pour tous les types: https://docs.mongodb.com/manual/reference/operator/query/type/#op._S_type

14
Farouk El kholy

Partage pour les futurs lecteurs.

Cette requête a fonctionné pour nous (requête exécutée à partir de boussole MongoDB ):

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

Une alternative qui n’a pas été mentionnée, mais qui peut être une option plus efficace pour certains (ne fonctionnera pas avec des entrées NULL) consiste à utiliser un index fragmenté (les entrées dans l’index n’existent que s’il existe quelque chose sur le terrain). Voici un exemple de jeu de données:

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 }

Maintenant, créez l'index fragmenté sur le champ imageUrl:

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

Maintenant, il y a toujours une chance (et en particulier avec un petit ensemble de données comme mon exemple) que, plutôt que d'utiliser un index, MongoDB utilise un balayage de table, même pour une requête d'index couverte potentielle. Il se trouve que cela me donne un moyen facile d’illustrer la différence ici:

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, donc les documents supplémentaires sans imageUrl sont renvoyés, ils sont simplement vides, pas ce que nous voulions. Juste pour confirmer pourquoi, faites une explication:

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
}

Donc, oui, un BasicCursor équivaut à un balayage de table, il n'a pas utilisé l'index. Forceons la requête à utiliser notre index fragmenté avec un 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" }

Et nous avons recherché le résultat recherché: seuls les documents contenant le champ renseigné sont renvoyés. Cela utilise également uniquement l'index (c'est-à-dire qu'il s'agit d'une requête d'index couverte). Par conséquent, seul l'index doit être en mémoire pour renvoyer les résultats.

Ceci est un cas d'utilisation spécialisé et ne peut pas être utilisé en général (voir les autres réponses pour ces options). En particulier, il convient de noter que, dans l’état actuel des choses, vous ne pouvez pas utiliser count() de cette manière (pour mon exemple, il renverra 6 et non 4), veuillez donc ne l’utiliser que s’il ya lieu.

2
Adam Comerford
db.<collectionName>.find({"IMAGE URL":{"$exists":"true"}, "IMAGE URL": {$ne: null}})
2
Berhanu Tarekegn