mongodb #mongoid
#mongodb #mongoid
Вопрос:
Допустим, у меня есть такие модели
class Band
include Mongoid::Document
embeds_many :albums
end
class Album
include Mongoid::Document
field :name, type: String
field :producer, type: String
embedded_in :band
end
Я хочу получить все группы, все альбомы которых выпущены «Джорджем Мартином».
Я пытался Band.where('albums.producer' => 'George Martin')
, но он соответствует всем группам, в продюсерах которых хотя бы один раз был Джордж Мартин.
Примеры:
Эта группа должна соответствовать (потому что все их альбомы были спродюсированы Джорджем Мартином):
{
"_id" : ObjectId("blabla"),
"albums" : [
{
"_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
"name" : "Violator",
"producer" : "George Martin"
}
]
}
Эта группа не должна соответствовать (потому что альбом » » был выпущен другим продюсером):
{
"_id" : ObjectId("blablabla"),
"albums" : [
{
"_id" : ObjectId("album1"),
"name" : "/",
"producer" : "George Martin"
},
{
"_id" : ObjectId("album2"),
"name" : " ",
"producer" : "Another producer"
}
]
}
Ответ №1:
Вы можете использовать $reduce для обработки вашего albums
массива. Задав начальное значение true
, вы можете условно установить значение false
, когда одна запись не равна «Джордж Мартин», используя $and
условие с аккумулятором. $match
конечный результат накопителя для выполнения фильтрации.
{
"$reduce": {
"input": "$albums",
"initialValue": true,
"in": {
$and: [
"$value",
{
$eq: [
"$this.producer",
"George Martin"
]
}
]
}
}
}
Вот игровая площадка Mongo для вашей справки.
Комментарии:
1. Похоже, это то, что я хочу! Смотрите раздел агрегации mongoid для перевода. Также какой индекс требуется для больших баз данных?
2. Это зависит от вашего шаблона запроса. Возможно, вы захотите ознакомиться с официальной документацией MongoDB .