【问题标题】:Mongoid query records that have all their embedded documents matching a criteria所有嵌入文档都符合条件的 Mongoid 查询记录
【发布时间】:2021-12-07 07:42:15
【问题描述】:

假设我有这样的模型

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

我想要的是所有专辑都由“George Martin”制作的乐队。

我尝试了Band.where('albums.producer' => 'George Martin'),但它匹配所有制作人中至少有一次 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"
    }
  ]
}

【问题讨论】:

    标签: mongodb mongoid


    【解决方案1】:

    您可以使用$reduce 来处理您的albums 数组。通过设置初始值true,可以有条件地将值设置为false,当一个条目不等于 "George Martin" 通过使用带有累加器的$and 条件。 $match累加器执行过滤的最终结果。

    {
        "$reduce": {
            "input": "$albums",
            "initialValue": true,
            "in": {
            $and: [
                "$$value",
                {
                $eq: [
                    "$$this.producer",
                    "George Martin"
                ]
                }
            ]
            }
        }
    }
    

    这里是Mongo playground 供您参考。

    【讨论】:

    • 这看起来就是我想要的!请参阅 mongoid 聚合部分进行翻译。大型数据库还需要什么样的索引?
    • 这取决于您的查询模式。您可能想查看this MongoDB official documentation
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    • 2011-07-23
    • 2017-04-24
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    相关资源
    最近更新 更多