Вопрос относительно объединения нескольких критериев any_of #Mongoid - PullRequest
13 голосов
/ 19 января 2011

У меня есть требование, где мне нужно выполнить запрос MongoDB, например:

db.collection.find({ $or : [{"field1" : "value1"}, {"field2" : "value2"}], 
$or : [{"field3" : "value3"}, {"field4" : "value4"}]}) 

т.е.

(field1 == value 1 or field2 == value2) and (field3 == value3 or field4 
== value4) 

Я хочу добиться этого с помощью цепочки критериев, потому что запрос получаетформируется динамически из разных частей кода.Но если я попытаюсь сделать что-то вроде следующего:

criteria = Collection.any_of({"field1" => "value1"}, {"field2" => 
"value2"})
criteria = criteria.any_of({"field3" => "value3"}, {"field4" => "value4"}) 

, я получу результирующий запрос, в котором все они объединены в один оператор $ или, например

db.collection.find({ $or : [{"field1" : "value1"}, {"field2" : "value2"}, 
{"field3" : "value3"}, {"field4" : "value4"}]}) 

Как достичь"а" из двух "any_of" с использованием цепочки критериев?

Ответы [ 5 ]

4 голосов
/ 10 января 2012

Вы можете написать это с помощью mongoid 2.4.0:

  Collection.all_of({"$or" => [{"field1" => "value1"}, {"field2" => "value2"}]}, {"$or" => [{"field3" => "value3"}, {"field4" => "value4"}]})
4 голосов
/ 19 января 2011

Вы можете сделать это, избегая any_of.

criteria = Collection.where('$or' => [{"field1" => "value1"}, {"field2" => "value2"}])
criteria = criteria.where('$or' => [{"field3" => "value3"}, {"field4" => "value4"}])
2 голосов
/ 11 июля 2014

Для Mongoid 3 и 4 есть относительно хороший способ объединения или критериев без слияния.

TL; DR

MyModel.all_of(MyModel.xxx.selector, MyModel.yyy.selector)

Монгойский сопровождающий Дурран показал вышеупомянутый трюк в этой проблеме Github https://github.com/mongoid/mongoid/issues/2170

Вы можете произвольно объединить критерии, используя ту же технику и некоторые хитрости с массивами, подобные этому:

selectors = []
selectors << MyModel.search(term) if term
selectors << MyModel.some_any_of if some_condition
selectors << MyModel.some_other_any_of if some_other_condition
...
MyMode..all_of(*selectors)

В каждой строке будет добавлено еще одно условие и .

Также стоит отметить, что вам не нужно создавать каждый селектор из модели. Вы можете получить исходную область видимости из вашей системы разрешений или что-то еще, и просто позвоните .selector, прежде чем добавлять дополнительные критерии.

1 голос
/ 01 декабря 2012

Мне понадобилось целую вечность, чтобы понять это правильно, но вот что сработало для меня:

scope :for_user, lambda {|user| 
    any_of(
      {recipient_id: Moped::BSON::ObjectId.from_string(user.id)}, 
      {sender_id: Moped::BSON::ObjectId.from_string(user.id)},
      {sender_email: user.email},
      {recipient_email: user.email}
    )
  }

Вы должны убедиться, что обернули индивидуальные критерии для вашего состояния $or в {}, поэтомучто он правильно вложен в ИЛИ.(С использованием Mongoid3 / Moped)

0 голосов
/ 08 января 2014

Это все еще так. Мне удалось обойти это только с помощью API драйвера Ruby Mongo напрямую.

...