2010-01-05 7 views
35

So habe ich ein eingebettetes Dokument, das Gruppenmitgliedschaften verfolgt. Jedes eingebettete Dokument hat eine ID, die auf die Gruppe in einer anderen Sammlung verweist, ein Startdatum und ein optionales Verfallsdatum.MongoDB Abfrage mit einer 'oder' Bedingung

Ich möchte für aktuelle Mitglieder einer Gruppe abfragen. "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 total. Ich kann es tun, indem zwei Abfragen ausgeführt und die Ergebnisse Zusammenführung, aber das scheint hässlich und erfordert Laden in allen sofort Ergebnissen. Oder ich könnte standardmäßig die Zeit bis zu einem gewissen willkürlichen Zeitpunkt in der fernen Zukunft ablaufen, aber das scheint noch hässliches und möglicherweise brüchig. In SQL würde ich es einfach auszudrücken, mit "(gültig bis> = Now()) OR (gültig bis IS NULL)" - aber ich weiß nicht, wie in Mongo, das zu tun.

Irgendwelche Ideen? Vielen Dank im Voraus.

+0

Analoge Frage: http://stackoverflow.com/questions/1945577/logical-or-for-two-different-Felder-in-dem-Abfrage-in-mongodb –

Antwort

2

Query objects in Mongo by default AND expressions together. Mongo currently does not include an OR operator for such queries, however there are ways to express such queries.

Use "in" oder "where". so etwas wie dieses

Sein Gehen sein:

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

Ziemlich cool, erstes Mal, dass ich mit Mongo verwendet, um eine Funktion zu sehen !! Der Nachteil ist natürlich, dass die Indizes nicht verwendet werden – Nico

1

Mit einem $ where Abfrage wird langsam sein, teilweise weil es keine Indizes verwenden können. Für diese Art von Problem denke ich, es wäre besser, einen hohen Wert für das speichern „gültig bis“ Feld, das als jetzt natürlich immer größer sein wird(). Sie können entweder ein sehr hohes Datum Millionen von Jahren in der Zukunft speichern, oder verwenden Sie einen firmeneigenen Typ, um nie anzugeben. Die Kreuztyp-Sortierreihenfolge ist unter http://www.mongodb.org/display/DOCS/Compare+Order+for+Types definiert. Ein leerer Regex oder MaxKey (wenn Ihre Sprache dies unterstützt) sind beide eine gute Wahl.

33

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

Im Falle von OR-Anweisungen, es sieht aus wie diese

SQL:

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

MongoDB:

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