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)
def entity_tags(entity, authz=None, edge_types=registry.pivots): """Do a search on tags of an entity.""" proxy = model.get_proxy(entity) graph = Graph(edge_types=edge_types) query = graph.query(authz=authz) for prop, value in proxy.itervalues(): if prop.type not in graph.edge_types: continue if prop.specificity(value) < 0.1: continue query.node(Node(prop.type, value), count=True) for res in query.execute(): field = res.node.type.group if res.count is not None and res.count > 1: yield (field, res.node.value, res.count)
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_proxies(proxies, authz, properties=None, limit=0): """Expand an entity's graph to find adjacent entities that are connected by a property (eg: Passport entity linked to a Person) or an Entity type edge (eg: Person connected to Company through Directorship). properties: list of FtM Properties to expand as edges. limit: max number of entities to return """ graph = Graph(edge_types=(registry.entity,)) for proxy in proxies: graph.add(proxy) queries = {} entity_ids = [proxy.id for proxy in proxies] # First, find all the entities pointing to the current one via a stub # property. This will return the intermediate edge entities in some # cases - then we'll use graph.resolve() to get the far end of the # edge. for prop in _expand_properties(proxies, properties): if not prop.stub: continue index = entities_read_index(prop.reverse.schema) field = "properties.%s" % prop.reverse.name queries[(index, prop.qname)] = field_filter_query(field, entity_ids) entities, counts = _counted_msearch(queries, authz, limit=limit) for entity in entities: graph.add(model.get_proxy(entity)) if limit > 0: graph.resolve() results = [] for prop in _expand_properties(proxies, properties): count = counts.get(prop.qname, 0) if not prop.stub: count = sum(len(p.get(prop)) for p in proxies) entities = set() for proxy in proxies: entities.update(_expand_adjacent(graph, proxy, prop)) if count > 0: item = { "property": prop.name, "count": count, "entities": entities, } results.append(item) # pprint(results) return results