模块:Mongoid::Association::EagerLoadable
- 定义于:
- lib/mongoid/association/eager_loadable.rb
Overview
此模块定义条件的预先加载行为。
实例方法摘要折叠
- #create_pipeline(current_assoc, mapping) ⇒ 对象
-
#ager_load ( Docs ) ⇒ Array<Mongoid::Document>
加载给定文档的关联。
-
#ager_load_with_lookup ⇒ Array<Mongoid::Document>
使用 $lookup 加载给定 document 的关联。
-
#ager_loadable? ⇒ true | false
指示条件是否包含应预先加载的关联包含项。
-
# preload (associations, Docs ) ⇒ 对象
加载给定文档的关联。
-
#preload_for_lookup(criteria) ⇒ 对象
加载给定文档的关联。
- #switch_local_and_foreign_fields?(association) ⇒ Boolean
实例方法详细信息
#create_pipeline(current_assoc, mapping) ⇒ 对象
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/mongoid/association/eager_loadable.rb', line 147 def create_pipeline(current_assoc, 映射) # 为子项和排序构建嵌套管道 pipeline_stages = [] # 对于 belongs_to 和 has_and_belongs_to_many,外键位于当前 document # 对于 has_many/has_one,外键位于相关 document 上 if switch_local_and_foreign_fields?(current_assoc) local_field = current_assoc.foreign_key foreign_field = current_assoc.primary_key else local_field = current_assoc.primary_key foreign_field = current_assoc.foreign_key end # 如果需要,构建带有嵌入式路径前缀的 'as'字段 as_field = current_assoc.名称.to_s 阶段 = { ' $lookup ' => { ' from ' => current_assoc.klass.集合.名称, 'localField' => local_field, 'foreignField' => foreign_field, 'as' => as_field } } # 如果在关联上定义了排序,则添加排序,或者默认为_id以获得一致的顺序 if current_assoc.来自一个购物车应用的order文档, sort_spec = current_assoc.来自一个购物车应用的order文档,.is_a?(哈希) ? current_assoc.来自一个购物车应用的order文档, : { current_assoc.来自一个购物车应用的order文档, => 1 } pipeline_stages << { '$sort' => sort_spec } else # 默认按_id排序,以保持插入顺序的一致性 pipeline_stages << { '$sort' => { '_id' => 1 } } end # 为子关联添加嵌套查找 # 子关联不需要 embedded_path 前缀,因为它们是从查找到的 document 中引用的 # 从映射中删除此类,以防止循环引用带来的无限循环 class_name = current_assoc.klass.to_s if child_assocs = 映射.删除(class_name) child_assocs.每 do |子项| pipeline_stages << create_pipeline(子项, 映射) end end # 始终添加管道,因为我们始终至少有 $sort 阶段[' $lookup ']['管道'] = pipeline_stages 阶段 end |
#ager_load ( Docs ) ⇒ Array< Mongoid::Document >
加载给定文档的关联。
22 23 24 25 26 |
# File 'lib/mongoid/association/eager_loadable.rb', line 22 def ager_load(docs) docs.点击 do |d| 预加载(条件.包含, d) if ager_loadable? end end |
#eager_load_with_lookup ⇒ 数组<Mongoid::Document>
使用 $lookup 加载给定 document 的关联。
如果任何关联的集合与根类位于不同的集群,则回退到 #includes 行为并记录警告。
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/mongoid/association/eager_loadable.rb', line 34 def Eager_load_with_lookup Offenders = cross_cluster_inclusions if Offenders.任何? root_client = klass.client_name Offender_list = Offenders.map { |a| "#{a.name} (#{a.klass.client_name})" }.连接 (JOIN)(' , ') Mongoid.记录器.WARN( 'agers_load 无法使用 $lookup聚合,因为以下关联 ' \ \"与 #{klass} 位于不同的集群(客户端:#{root_client}):\" \ \"#{offender_list}。 #includes 行为。\") returnagerd_load(docs_for_lookup_fallback)end preload_for_lookup(criteria)end |
#ager_loadable? ⇒ true | false
指示条件是否包含应预先加载的关联包含项。
13 14 15 |
# File 'lib/mongoid/association/eager_loadable.rb', line 13 def ager_loadable? !条件.包含.空? end |
# preload (associations, Docs ) ⇒对象
加载给定 document 的关联。这将以递归方式完成,以加载给定文档的关联文档的关联。
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/mongoid/association/eager_loadable.rb', line 57 def 预加载(关联, docs) assoc_map = 关联.GROUP_BY(和:inverse_class_name) docs_map = {} 队列 = [ klass.to_s ] # 考虑单集合继承 队列.推动(klass.root_class.to_s) if klass != klass.root_class while klass = 队列.转变 来年 除非 作为 = assoc_map.删除(klass) 作为.每 do |assoc| 队列 << assoc.class_name # 如果此类嵌套在包含树中,则仅加载文档 # 用于其上方的关联。 如果没有父关联, # 我们将包含传递给此方法的文档中的文档。 ds = docs ds = assoc.parent_inclusions.map { |p| docs_map[p].to_a }.展平 if assoc.parent_inclusions.长度 > 0 res = assoc.关系.Eager_Loader([ assoc ], ds).运行 docs_map[assoc.名称] ||= [].to_set docs_map[assoc.名称].合并(merge)(res) end end end |
# preload_for_lookup (criteria) ⇒ 对象
加载给定 document 的关联。这将以递归方式完成,以加载给定文档的关联文档的关联。
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/mongoid/association/eager_loadable.rb', line 92 def preload_for_lookup(条件) assoc_map = 条件.包含.GROUP_BY(和:inverse_class_name) # 首先匹配 管道 = 条件.选择器.to_pipeline # then sort、skip、limit 管道.concat(条件..to_pipeline_for_lookup) # 考虑单集合继承 root_class = klass.root_class if assoc_map[klass.to_s] assoc_map[klass.to_s].每 do |assoc| # 为每个顶级关联创建映射副本,以避免突变问题 管道 << create_pipeline(assoc, assoc_map.dup) end end if klass != root_class && assoc_map[root_class.to_s] assoc_map[root_class.to_s].每 do |assoc| # 为每个顶级关联创建映射副本,以避免突变问题 管道 << create_pipeline(assoc, assoc_map.dup) end end Eager.new(条件.包含, [], true, 管道).运行 end |