mptt クエリセットのすべての先祖を取得するための効率的なアルゴリズムを持っている人はいますか? これまでのところ、私が考えることができる最高のものは次のようなものです:
def qs_ancestors(queryset):
if isinstance(queryset, EmptyQuerySet):
return queryset
queryset_aggs = queryset.values_list('tree_id', 'level').annotate(max_lft=Max('lft'), min_rght=Min('rght'))
new_queryset = queryset.none()
for tree_id, level, max_lft, min_rght in queryset_aggs:
ancestors = MyModel.objects.filter(
tree_id=tree_id,
level__lt=level,
lft__lte=max_lft,
rght__gte=min_rght,
)
new_queryset = ancestors | new_queryset
return new_queryset
このアプローチには 2 つの問題があります。
- 隣り合っていないブランチがあると失敗します (つまり、実際には機能しません)。
- 最終的なクエリに句が含まれてしまうため、非常に非効率的で
number_of_trees*number_of_levels
あり、非常に高速に巨大化する可能性があります
祖先を別の場所にキャッシュすることにオープンですが、効率的に行う方法が思いつきません。先祖のIDのコンマ区切りリストを含むフィールドを追加してから、GROUP_CONCAT
(私はMySQLにいます)エクストラ内で実行することを検討しましたが、それは巨大/遅くなる可能性があると思います.