MongoDB-Abfrage mit einer 'oder' Bedingung


74

Ich habe also ein eingebettetes Dokument, das Gruppenmitgliedschaften verfolgt. Jedes eingebettete Dokument verfügt über eine ID, die auf die Gruppe in einer anderen Sammlung verweist, ein Startdatum und ein optionales Ablaufdatum.

Ich möchte nach aktuellen Mitgliedern einer Gruppe fragen. "Aktuell" bedeutet, dass die Startzeit kleiner als die aktuelle Zeit ist und die Ablaufzeit größer als die aktuelle Zeit ODER null ist.

Diese bedingte Abfrage blockiert mich völlig. Ich könnte es tun, indem ich zwei Abfragen ausführe und die Ergebnisse zusammenführe, aber das scheint hässlich und erfordert das gleichzeitige Laden aller Ergebnisse. Oder ich könnte die Ablaufzeit auf ein beliebiges Datum in ferner Zukunft festlegen, aber das scheint noch hässlicher und möglicherweise spröde zu sein. In SQL würde ich es einfach mit "(expires> = Now ()) OR (expires IS NULL)" ausdrücken - aber ich weiß nicht, wie ich das in Mongo machen soll.

Irgendwelche Ideen? Vielen Dank im Voraus.


Antworten:



64

Falls es jemand nützlich findet, übersetzt www.querymongo.com zwischen SQL und MongoDB, einschließlich OR-Klauseln. Es kann sehr hilfreich sein, um die Syntax herauszufinden, wenn Sie das SQL-Äquivalent kennen.

Bei OR-Anweisungen sieht es so aus

SQL:

SELECT * FROM collection WHERE columnA = 3 OR columnB = 'string';

MongoDB:

db.collection.find({
    "$or": [{
        "columnA": 3
    }, {
        "columnB": "string"
    }]
});

4

Abfragen von Objekten in Mongo standardmäßig UND-Ausdrücke zusammen. Mongo enthält derzeit keinen ODER-Operator für solche Abfragen. Es gibt jedoch Möglichkeiten, solche Abfragen auszudrücken.

Verwenden Sie "in" oder "where".

Es wird ungefähr so ​​sein:

db.mycollection.find( { $where : function() { 
return ( this.startTime < Now() && this.expireTime > Now() || this.expireTime == null ); } } );

Ziemlich cool, zum ersten Mal sehe ich eine Funktion, die mit Mongo verwendet wird !! Der Nachteil ist natürlich, dass die Indizes nicht verwendet werden
Nico

Dies ist eine sehr alte Antwort. In der Zwischenzeit hat MongoDB hinzugefügt $or.
Dan Dascalescu

4

db.Lead.find (

{"name": {'$regex' : '.*' + "Ravi" + '.*'}},
{
"$or": [{
    'added_by':"arunkrishna@aarux.com"
}, {
    'added_by':"aruna@aarux.com"
}]
}

);


2

Die Verwendung einer $whereAbfrage ist langsam, teilweise weil keine Indizes verwendet werden können. Für diese Art von Problem halte ich es für besser, einen hohen Wert für das Feld "expires" zu speichern, der natürlich immer größer als Now () ist. Sie können entweder ein sehr hohes Datum in Millionen von Jahren in der Zukunft speichern oder einen separaten Typ verwenden, um "nie" anzuzeigen. Die Quer Typ Sortierreihenfolge wird an definierten hier .

Ein leerer Regex oder MaxKey (wenn Ihre Sprache dies unterstützt) sind beide eine gute Wahl.


2

MongoDB-Abfrage mit einer 'oder' Bedingung

db.getCollection('movie').find({$or:[{"type":"smartreply"},{"category":"small_talk"}]})

MongoDB-Abfrage mit einer kombinierten Bedingung 'oder', 'und'.

db.getCollection('movie').find({"applicationId":"2b5958d9629026491c30b42f2d5256fa8",$or:[{"type":"smartreply"},{"category":"small_talk"}]})
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.