def test_P(self): # verify that the order of operations is respected assert "and(eq(a),lt(b))" == str(P.eq("a").and_(P.lt("b"))) assert "and(or(lt(b),gt(c)),neq(d))" == str( P.lt("b").or_(P.gt("c")).and_(P.neq("d"))) assert "and(or(lt(b),gt(c)),or(neq(d),gte(e)))" == str( P.lt("b").or_(P.gt("c")).and_(P.neq("d").or_(P.gte("e"))))
async def drop_vertices(goblin_app, timestamp): session = await goblin_app.session() for attempt in range(10): traversal = session.g.V().has("last_modified", P.lt(timestamp)).count() try: total = await traversal.next() except GremlinServerError as e: logger.error(f"Backing off: {e!s}\n{traceback.format_exc()}") await backoff(attempt) logger.info(f"Found {total} stale vertices to drop.") if not total: return with TQDMK8S( desc="Purging Old Vertices", dynamic_ncols=True, file=sys.stdout, total=None, ) as progress_bar: batch = 100 dropped = 1 while dropped: for attempt in range(10): traversal = ( session.g.V() .has("last_modified", P.lt(timestamp)) .limit(batch) .sideEffect(__.drop()) .count() ) try: dropped = await traversal.next() except GremlinServerError as e: logger.error(f"Backing off: {e!s}\n{traceback.format_exc()}") await backoff(attempt) progress_bar.update(1)
def test_P(self): result = {'@type': 'g:P', '@value': { 'predicate': 'and', 'value': [{ '@type': 'g:P', '@value': { 'predicate': 'or', 'value': [{ '@type': 'g:P', '@value': {'predicate': 'lt', 'value': 'b'} }, {'@type': 'g:P', '@value': {'predicate': 'gt', 'value': 'c'}} ] } }, {'@type': 'g:P', '@value': {'predicate': 'neq', 'value': 'd'}}]}} assert result == json.loads( self.graphson_writer.writeObject(P.lt("b").or_(P.gt("c")).and_(P.neq("d")))) result = {'@type': 'g:P', '@value': {'predicate':'within','value': [{"@type": "g:Int32", "@value": 1},{"@type": "g:Int32", "@value": 2}]}} assert result == json.loads(self.graphson_writer.writeObject(P.within([1, 2]))) assert result == json.loads(self.graphson_writer.writeObject(P.within(1, 2))) result = {'@type': 'g:P', '@value': {'predicate':'within','value': [{"@type": "g:Int32", "@value": 1}]}} assert result == json.loads(self.graphson_writer.writeObject(P.within([1]))) assert result == json.loads(self.graphson_writer.writeObject(P.within(1)))
def _clean_up_relationships(self, urn: PartialUrn, cutoff: datetime) -> None: logger.debug("Cleaning up edges owned by %s discovered before %s", self.generate_vertex_id(urn), cutoff) (self.g.V(self.generate_vertex_id(urn)).bothE().as_("edge").has( "_edge_owner", self.generate_vertex_id(urn)).where( __.values("_discovery_time").is_(P.lt( cutoff.isoformat()))).select("edge").drop()).iterate()
async def drop_edges(session, label, entity_id, timestamp=None, both=False, names=None): for attempt in range(10): traversal = session.g.V().has(label, f"{label}_id", entity_id) if both: traversal = traversal.bothE("relationship") else: traversal = traversal.outE("relationship") if names: traversal = traversal.has("name", P.within(*names)) traversal = traversal.has("last_modified", P.lt(timestamp)) traversal = traversal.drop() try: return await traversal.toList() except GremlinServerError as e: logger.error(f"Backing off: {e!s}\n{traceback.format_exc()}") await backoff(attempt)
def test_P(self): result = {'@type': 'g:P', '@value': { 'predicate': 'and', 'value': [{ '@type': 'g:P', '@value': { 'predicate': 'or', 'value': [{ '@type': 'g:P', '@value': {'predicate': 'lt', 'value': 'b'} }, {'@type': 'g:P', '@value': {'predicate': 'gt', 'value': 'c'}} ] } }, {'@type': 'g:P', '@value': {'predicate': 'neq', 'value': 'd'}}]}} assert result == json.loads( self.graphson_writer.writeObject(P.lt("b").or_(P.gt("c")).and_(P.neq("d"))))
def delete_resource_of_type_in_account_region( self, cloud_name: str, service: str, resource_type: str, account_id: str, region: str, cutoff: Optional[datetime], ) -> None: """Delete resources of type in account and region unless in list of URNs. This is used primarily to clean up old resources. Arguments: cloud_name: The name of the cloud in question (e.g. ``aws``) account_id: Cloud Account ID (e.g. ``111111111111``) region: Cloud region (e.g. ``'eu-west-2'``) service: Service name (e.g. ``'ec2'``) resource_type: Resource Type (e.g. ``'instance'``) cutoff: Delete any resource discovered before this time """ partial_urn = PartialUrn( cloud_name=cloud_name, service=service, account_id=account_id, region=region, resource_type=resource_type, ) logger.debug( "Deleting resources that match %s that were discovered before %s", partial_urn, cutoff) traversal = self._lookup_resource(partial_urn=partial_urn) if cutoff: traversal.where( __.values("_discovery_time").is_(P.lt(cutoff.isoformat()))) traversal.drop().iterate()
def get_known_associates(person_id): logging.info('Request Received: Get Known Associates') g = setup_graph() try: params = app.current_request.query_params if app.current_request.query_params else {} threshold = float(params.get('threshold', '0.5')) originating_person = get_person(person_id=person_id, g=g) # DEDUP people = g.withSack(1.0).V(originating_person).repeat(__.outE('knows').sack(Operator.mult).by('weight') .inV()).until(__.sack().is_(P.lt(threshold))).emit()\ .as_('b').sack().as_('a').select('a', 'b').toList() # Unfortunately the above query will include the final node which goes below the threshold # I'm sure there is a way to improve this query to not include it! Until then, handle explicitly. # Similarly, I am deduping in Python - but ideally I would push this into the query (it's not a simple dedup # since I need to retain the max edge weight to make sure I don't mistakenly filter a dupe with < threshold) people = list( set([person['b'] for person in people if person['a'] >= 0.5])) logging.info("Found People: %s" % str(people)) results = [] for person in people: results.append(vertex_to_json(vertex=person, g=g)) except (ValueError, AttributeError, TypeError) as e: logging.error(e, exc_info=True) raise BadRequestError('Could not retrieve known associates. Error: ' + str(e)) logging.info("Successfully retrieved known associates") return {'known_associates': results}
def test_traversals(self, remote_connection): statics.load_statics(globals()) g = traversal().withRemote(remote_connection) assert long(6) == g.V().count().toList()[0] # # assert Vertex(1) == g.V(1).next() assert Vertex(1) == g.V(Vertex(1)).next() assert 1 == g.V(1).id_().next() assert Traverser(Vertex(1)) == g.V(1).nextTraverser() assert 1 == len(g.V(1).toList()) assert isinstance(g.V(1).toList(), list) results = g.V().repeat(__.out()).times(2).name results = results.toList() assert 2 == len(results) assert "lop" in results assert "ripple" in results # # assert 10 == g.V().repeat(__.both()).times(5)[0:10].count().next() assert 1 == g.V().repeat(__.both()).times(5)[0:1].count().next() assert 0 == g.V().repeat(__.both()).times(5)[0:0].count().next() assert 4 == g.V()[2:].count().next() assert 2 == g.V()[:2].count().next() # # results = g.withSideEffect( 'a', ['josh', 'peter' ]).V(1).out('created').in_('created').values('name').where( P.within('a')).toList() assert 2 == len(results) assert 'josh' in results assert 'peter' in results # # results = g.V().out().profile().toList() assert 1 == len(results) assert 'metrics' in results[0] assert 'dur' in results[0] # # results = g.V().has('name', 'peter').as_('a').out('created').as_('b').select( 'a', 'b').by(__.valueMap()).toList() assert 1 == len(results) assert 'peter' == results[0]['a']['name'][0] assert 35 == results[0]['a']['age'][0] assert 'lop' == results[0]['b']['name'][0] assert 'java' == results[0]['b']['lang'][0] assert 2 == len(results[0]['a']) assert 2 == len(results[0]['b']) # # results = g.V(1).inject(g.V(2).next()).values('name').toList() assert 2 == len(results) assert 'marko' in results assert 'vadas' in results # # results = g.V().has('person', 'name', 'marko').map( lambda: ("it.get().value('name')", "gremlin-groovy")).toList() assert 1 == len(results) assert 'marko' in results # # # this test just validates that the underscored versions of steps conflicting with Gremlin work # properly and can be removed when the old steps are removed - TINKERPOP-2272 results = g.V().filter_( __.values('age').sum_().and_(__.max_().is_(P.gt(0)), __.min_().is_(P.gt(0)))).range_( 0, 1).id_().next() assert 1 == results # # # test binding in P results = g.V().has('person', 'age', Bindings.of('x', P.lt(30))).count().next() assert 2 == results # # # test dict keys which can only work on GraphBinary and GraphSON3 which include specific serialization # types for dict if not isinstance(remote_connection._client._message_serializer, GraphSONSerializersV2d0): results = g.V().has( 'person', 'name', 'marko').elementMap("name").groupCount().next() assert { HashableDict.of({ T.id: 1, T.label: 'person', 'name': 'marko' }): 1 } == results if not isinstance(remote_connection._client._message_serializer, GraphSONSerializersV2d0): results = g.V().has('person', 'name', 'marko').both('knows').groupCount().by( __.values('name').fold()).next() assert {tuple(['vadas']): 1, tuple(['josh']): 1} == results
def test_P(self): assert """{"@type":"g:P","@value":{"predicate":"and","value":[{"@type":"g:P","@value":{"predicate":"or","value":[{"@type":"g:P","@value":{"predicate":"lt","value":"b"}},{"@type":"g:P","@value":{"predicate":"gt","value":"c"}}]}},{"@type":"g:P","@value":{"predicate":"neq","value":"d"}}]}}""" == self.graphson_writer.writeObject( P.lt("b").or_(P.gt("c")).and_(P.neq("d")))
def test_P(self): # verify that the order of operations is respected assert "and(eq(a),lt(b))" == str(P.eq("a").and_(P.lt("b"))) assert "and(or(lt(b),gt(c)),neq(d))" == str(P.lt("b").or_(P.gt("c")).and_(P.neq("d"))) assert "and(or(lt(b),gt(c)),or(neq(d),gte(e)))" == str( P.lt("b").or_(P.gt("c")).and_(P.neq("d").or_(P.gte("e"))))