2010-10-04 9 views
5

Potrzebuję napisać zapytanie MongoDB o formularzu "A LUB B OR (C i D)", aby zwrócić niektóre rekordy. Używamy Mongoida do dostępu do danych naszych modeli.Jak piszesz pytanie "(A OR B) I (A OR C)" z Mongoidem?

Poszerzyłem to zapytanie o "(A OR B OR C) ORAZ (A LUB B OR D)" i miałem nadzieję, że za pomocą metody Mongoid's Criteria any_of wykonam to, co chcę, ale to jest rozszerzone "A OR B LUB C OR A LUB B OR D" przed wysłaniem do bazy danych.

Czy istnieje sposób na zbudowanie tego zapytania lub czy muszę zbudować jedno zapytanie, aby wykonać A OR B, a drugie wykonać C i D i złączyć je?

Odpowiedz

0

Wygląda na to, że to błąd w mongo, ale mam problem z ustaleniem, gdzie są zgłaszane/śledzone problemy z mongo.

> db.things.insert({x : 1, y: 2}); 
> db.things.insert({x : 2, y: 3}); 
> db.things.insert({x : 3, y: 4}); 
> db.things.find({ $or : [{x:1,x:2}], $or : [{y:1,y:2}] }); 
{ ..., "x" : 1, "y" : 2 } 
{ ..., "x" : 2, "y" : 3 } 
+1

wielu '$ or' sprawozdania nie ma sensu. Zastanów się, co to będzie po przekonwertowaniu na obiekt BSON. Ta ostatnia zastąpi pierwszą. Dodatkowo, twoje dokumenty selektora są winne tego samego błędu; w zasadzie szukasz "$ lub: [{y: 2}]". –

+0

Wiele instrukcji '$ lub' ma sens, po prostu nie są obsługiwane przez mongo (czy istnieje link do zweryfikowania tego, btw?). Wygląda na to, że najlepszą praktyką jest ręczne przekształcanie spójników w postaci '(A OR B) I (A LUB C)' w disjunkcje typu 'A OR (B/C)' w celu użycia '$ lub', ponieważ mongoid nie zrobimy tego dla nas. –

+0

Ma to sens w logice logiki Boolean, ale nie w sensie JSON Object, który nie pozwala na duplikowanie kluczy. Masz rację, ponieważ DNF jest właściwym sposobem wyrażenia zapytania. –

3

(Edit: Właśnie zauważyłem to pytanie 3 lat nie mam pojęcia, dlaczego to właśnie pokazał.).

Chcesz coś takiego:

Model.any_of(a, b, c) 

Gdzie a , b i c są dokumentami selektora (które, pamiętaj, są ANDedowane z wieloma klauzulami).

Na przykład, jeśli pytania są następujące:

{a: 1} 
{b: 1} 
{c: 1, d: 1} 

Wtedy użyłby:

Model.any_of({a: 1}, {b: 1}, {c: 1, d: 1}) 

byłoby to wygenerowanie zapytania jak:

models.find({$or: [{a: 1}, {b: 1}, {c: 1, d: 1}]}) 
+0

Zacząłem nagrodę za to pytanie, ponieważ jest to dobre pytanie bez dobrych odpowiedzi. – Andrew

+0

Aha, rozumiem. Mam nadzieję, że mój jest zadowalający. :) –

+0

W jaki sposób 'any_of' daje' (A OR B) AND (A OR C) 'tutaj? –

Powiązane problemy