所有嵌入文档都符合条件的 Mongoid 查询记录

Posted

技术标签:

【中文标题】所有嵌入文档都符合条件的 Mongoid 查询记录【英文标题】:Mongoid query records that have all their embedded documents matching a criteria 【发布时间】: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"
    
  ]

【问题讨论】:

【参考方案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。

以上是关于所有嵌入文档都符合条件的 Mongoid 查询记录的主要内容,如果未能解决你的问题,请参考以下文章

Mongoid查询嵌套embed文档通过属于和嵌入多个

Mongoid:嵌入文档在父级构造时自动初始化

Factory Girl + Mongoid 在夹具中嵌入文档

Mongoid 按值或默认值查询

MS-Access 2007:查询与至少有一条记录符合指定条件的个人相关的所有记录

mysql随机查询符合条件的几条记录