feat(api): add api /ci_type_relations/path

This commit is contained in:
pycook
2024-09-26 20:32:21 +08:00
parent bbcc0f986e
commit e369a55333
3 changed files with 48 additions and 2 deletions

View File

@@ -3,6 +3,7 @@
from collections import defaultdict
import copy
import networkx as nx
import toposort
from flask import abort
from flask import current_app
@@ -845,6 +846,29 @@ class CITypeRelationManager(object):
return ids
@staticmethod
def find_path(source_type_id, target_type_ids):
source_type_id = int(source_type_id)
target_type_ids = map(int, target_type_ids)
graph = nx.DiGraph()
def get_children(_id):
children = CITypeRelation.get_by(parent_id=_id, to_dict=False)
for i in children:
if i.child_id != _id:
graph.add_edge(i.parent_id, i.child_id)
get_children(i.child_id)
get_children(source_type_id)
paths = list(nx.all_simple_paths(graph, source_type_id, target_type_ids))
del graph
return paths
@staticmethod
def _wrap_relation_type_dict(type_id, relation_inst):
ci_type_dict = CITypeCache.get(type_id).to_dict()

View File

@@ -432,6 +432,13 @@ class Search(object):
return SearchFromDB(q, use_ci_filter=True, only_ids=True, count=100000).search()
@staticmethod
def _filter_target_ids(target_ids, type_ids, q):
if not q.startswith('_type:'):
q = "_type:({}),{}".format(";".join(map(str, type_ids)), q)
return SearchFromDB(q, ci_ids=target_ids, use_ci_filter=False, only_ids=True, count=100000).search()
@staticmethod
def _path2level(src_type_id, target_type_ids, path):
if not src_type_id or not target_type_ids:
@@ -502,6 +509,7 @@ class Search(object):
ci_ids = [j for i in paths for j in i]
response, _, _, _, _, _ = SearchFromDB("_type:({})".format(";".join(map(str, types))),
use_ci_filter=False,
ci_ids=list(map(int, ci_ids)),
count=1000000).search()
id2ci = {str(i.get('_id')): i for i in response}
@@ -539,6 +547,8 @@ class Search(object):
source_ids = self._get_src_ids(source)
graph, target_ids = self._build_graph(source_ids, level2type, target['type_ids'], acl)
if target.get('q'):
target_ids = self._filter_target_ids(target_ids, target['type_ids'], target['q'])
paths = self._find_paths(graph, source_ids, set(target_ids))
del graph