def entity_expand(entity, collection_ids, edge_types, limit, properties=None, authz=None): """Expand an entity's graph to find adjacent entities that are connected by a common property value(eg: having the same email or phone number), a property (eg: Passport entity linked to a Person) or an Entity type edge. (eg: Person connected to Company through Directorship) collection_ids: list of collection_ids to search edge_types: list of FtM Types to expand as edges properties: list of FtM Properties to expand as edges. limit: max number of entities to return """ proxy = model.get_proxy(entity) node = Node.from_proxy(proxy) graph = Graph(edge_types=edge_types) graph.add(proxy) query = graph.query(authz=authz, collection_ids=collection_ids) # Get relevant property set props = set(proxy.schema.properties.values()) props = [p for p in props if p.type in graph.edge_types] properties = ensure_list(properties) if len(properties): props = [p for p in props if p.name in properties] # Query for reverse properties for prop in props: if prop.stub: query.edge(node, prop.reverse, limit=limit, count=True) query.execute() # Fill in missing graph entities: if limit > 0: graph.resolve() for prop in props: count = len(proxy.get(prop)) if prop.stub: for res in query.patterns: if res.prop == prop.reverse: count = res.count proxies = set() # Too much effort to do this right. This works, too: for edge in graph.get_adjacent(node, prop=prop): for part in (edge.proxy, edge.source.proxy, edge.target.proxy): if part is not None and part != proxy: proxies.add(part) if count > 0: yield (prop, count, proxies)
def _expand_adjacent(graph, proxy, prop): """Return all proxies related to the given proxy/prop combo as an array. This creates the very awkward return format for the API, which simply gives you a list of entities and lets the UI put them in some meaningful relation. Gotta revise this some day....""" # Too much effort to do this right. This works, too: adjacent = set() node = Node.from_proxy(proxy) for edge in graph.get_adjacent(node, prop=prop): for part in (edge.proxy, edge.source.proxy, edge.target.proxy): if part is not None and part != proxy: adjacent.add(part) return adjacent
def entity_references(entity, authz=None): """Given a particular entity, find all the references to it from other entities, grouped by the property where they are used.""" proxy = model.get_proxy(entity) node = Node.from_proxy(proxy) graph = Graph() query = graph.query(authz=authz) for prop in proxy.schema.properties.values(): if not prop.stub: continue query.edge(node, prop.reverse, count=True) for res in query.execute(): if res.count > 0: yield (res.prop, res.count)