我有一个ltree
结构(Postgres ltree 扩展)排列的数据库记录。
我想将这些项目过滤到当前选择的最外层祖先。
测试用例:
[11, 111, 1111, 2, 22, 222, 2221, 2222] => [11, 2];
[1, 11, 111, 1111, 1112, 2, 22, 222, 2221, 2222, 3, 4, 5] => [1, 2, 3, 4, 5];
[1111, 1112, 2221, 2222] => [1111, 1112, 2221, 2222];
1
|_1.1
| |_1.1.1
| |_1.1.1.1
| |_1.1.1.2
2
|_2.2
| |_2.2.2
| |_2.2.2.1
| |_2.2.2.2
3
|
4
|
5
我已经像这样在Ruby中实现了这个。
def fetch_outer_most_items(identifiers)
ordered_items = Item.where(id: identifiers).order("path DESC")
items_array = ordered_items.to_a
outer_most_item_ids = []
while(items_array.size > 0) do
item = items_array.pop
outer_most_item_ids.push(item.id)
duplicate_ids = ordered_items.where("items.path <@ '#{item.path}'").pluck(:id)
if duplicate_ids.any?
items_array = items_array.select { |i| !duplicate_ids.include?(i.id) }
end
end
return ordered_items.where(id: outer_most_item_ids)
end
我通过递归消除了后代作为重复项。我很确定有一种 SQL 方法可以做到这一点,这将是首选的解决方案,因为它会触发 n+1 个查询。理想情况下,我会将此函数添加为Item
模型的命名范围。
请问有什么指点吗?