Записи запросов Mongoid, все встроенные документы которых соответствуют критериям

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 .