private void assertNoIndexSeeks( Result result ) { assertThat( result.stream().count(), is( 1L ) ); String planDescription = result.getExecutionPlanDescription().toString(); assertThat( planDescription, containsString( "NodeByLabel" ) ); assertThat( planDescription, not( containsString( "IndexSeek" ) ) ); }
@Test public void creatingNormalIndexWithFulltextProviderMustThrow() { db = createDatabase(); assertThat( FulltextIndexProviderFactory.DESCRIPTOR.name(), is( "fulltext-1.0" ) ); // Sanity check that this test is up to date. try ( Transaction tx = db.beginTx() ) { db.execute( "call db.createIndex( \":User(searchableString)\", \"" + FulltextIndexProviderFactory.DESCRIPTOR.name() + "\" );" ).close(); tx.success(); } catch ( QueryExecutionException e ) { assertThat( e.getMessage(), containsString( "only supports fulltext index descriptors" ) ); } try ( Transaction tx = db.beginTx() ) { long indexCount = db.execute( DB_INDEXES ).stream().count(); assertThat( indexCount, is( 0L ) ); tx.success(); } }
try ( Result result = db.execute( format( QUERY_RELS, "rels", "value" ) ) ) assertThat( result.stream().count(), is( 0L ) );
try ( Result result = db.execute( format( QUERY_NODES, "nodes", "value" ) ) ) assertThat( result.stream().count(), is( 0L ) );
assertThat( result.stream().count(), is( 0L ) );
assertThat( result.stream().count(), is( 0L ) );
public <T> List<T> queryForNode(String query, Function<Map<String, Object>, T> transformer) { long start = currentTimeMillis(); try (Transaction tx = db.beginTx()) { try (Result nodes = db.execute(query, singletonMap("value", value))) { return nodes.stream().map(transformer).collect(Collectors.toList()); } finally { tx.success(); if (log.isDebugEnabled()) log.debug(format("(%s) search on label:%s and prop:%s took %d", Thread.currentThread(), label, prop, currentTimeMillis() - start)); } } } }
@Override public AnyValue apply(org.neo4j.kernel.api.proc.Context ctx, AnyValue[] input) throws ProcedureException { Map<String, Object> params = functionParams(input, inputs, defaultValueMapper); try (Result result = api.execute(statement, params)) { // resourceTracker.registerCloseableResource(result); // TODO if (!result.hasNext()) return null; if (output.isEmpty()) { return ValueUtils.of(result.stream().collect(Collectors.toList())); } List<String> cols = result.columns(); if (cols.isEmpty()) return null; if (!forceSingle && outType instanceof ListType) { ListType listType = (ListType) outType; AnyType innerType = listType.innerType(); if (innerType instanceof MapType) return ValueUtils.of(result.stream().collect(Collectors.toList())); if (cols.size() == 1) return ValueUtils.of(result.stream().map(row -> row.get(cols.get(0))).collect(Collectors.toList())); } else { Map<String, Object> row = result.next(); if (outType instanceof MapType) return ValueUtils.of(row); if (cols.size() == 1) return ValueUtils.of(row.get(cols.get(0))); } throw new IllegalStateException("Result mismatch " + cols + " output type is " + output); } } }, true);
@Procedure("apoc.case") @Description("apoc.case([condition, query, condition, query, ...], elseQuery:'', params:{}) yield value - given a list of conditional / read-only query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters") public Stream<MapResult> whenCase(@Name("conditionals") List<Object> conditionals, @Name(value="elseQuery", defaultValue = "") String elseQuery, @Name(value="params", defaultValue = "") Map<String, Object> params) { if (params == null) params = Collections.emptyMap(); if (conditionals.size() % 2 != 0) { throw new IllegalArgumentException("Conditionals must be an even-sized collection of boolean, query entries"); } Iterator caseItr = conditionals.iterator(); while (caseItr.hasNext()) { boolean condition = (Boolean) caseItr.next(); String ifQuery = (String) caseItr.next(); if (condition) { return db.execute(withParamMapping(ifQuery, params.keySet()), params).stream().map(MapResult::new); } } if (elseQuery.isEmpty()) { return Stream.of(new MapResult(Collections.emptyMap())); } else { return db.execute(withParamMapping(elseQuery, params.keySet()), params).stream().map(MapResult::new); } }
@Procedure(mode = WRITE) @Description("apoc.cypher.doIt(fragment, params) yield value - executes writing fragment with the given parameters") public Stream<MapResult> doIt(@Name("cypher") String statement, @Name("params") Map<String, Object> params) { if (params == null) params = Collections.emptyMap(); return db.execute(withParamMapping(statement, params.keySet()), params).stream().map(MapResult::new); }
@Procedure @Description("apoc.cypher.run(fragment, params) yield value - executes reading fragment with the given parameters") public Stream<MapResult> run(@Name("cypher") String statement, @Name("params") Map<String, Object> params) { if (params == null) params = Collections.emptyMap(); return db.execute(withParamMapping(statement, params.keySet()), params).stream().map(MapResult::new); }
@Procedure("apoc.help") @Description("Provides descriptions of available procedures. To narrow the results, supply a search string. To also search in the description text, append + to the end of the search string.") public Stream<HelpResult> info(@Name("proc") String name) throws Exception { boolean searchText = false; if (name != null) { name = name.trim(); if (name.endsWith("+")) { name = name.substring(0, name.lastIndexOf('+')).trim(); searchText = true; } } String filter = " WHERE name starts with 'apoc.' " + " AND ({name} IS NULL OR toLower(name) CONTAINS toLower({name}) " + " OR ({desc} IS NOT NULL AND toLower(description) CONTAINS toLower({desc}))) " + "RETURN type, name, description, signature "; String query = "WITH 'procedure' as type CALL dbms.procedures() yield name, description, signature " + filter + " UNION ALL " + "WITH 'function' as type CALL dbms.functions() yield name, description, signature " + filter; return db.execute(query, map("name", name, "desc", searchText ? name : null)) .stream().map(HelpResult::new); } }
@Procedure("apoc.when") @Description("apoc.when(condition, ifQuery, elseQuery:'', params:{}) yield value - based on the conditional, executes read-only ifQuery or elseQuery with the given parameters") public Stream<MapResult> when(@Name("condition") boolean condition, @Name("ifQuery") String ifQuery, @Name(value="elseQuery", defaultValue = "") String elseQuery, @Name(value="params", defaultValue = "") Map<String, Object> params) { if (params == null) params = Collections.emptyMap(); String targetQuery = condition ? ifQuery : elseQuery; if (targetQuery.isEmpty()) { return Stream.of(new MapResult(Collections.emptyMap())); } else { return db.execute(withParamMapping(targetQuery, params.keySet()), params).stream().map(MapResult::new); } }
@Description("apoc.graph.fromCypher('kernelTransaction',{params},'name',{properties}) - creates a virtual graph object for later processing") @Procedure public Stream<VirtualGraph> fromCypher(@Name("kernelTransaction") String statement, @Name("params") Map<String,Object> params,@Name("name") String name, @Name("properties") Map<String,Object> properties) { params = params == null ? Collections.emptyMap() : params; Set<Node> nodes = new HashSet<>(1000); Set<Relationship> rels = new HashSet<>(1000); Map<String,Object> props = new HashMap<>(properties); db.execute(Cypher.withParamMapping(statement, params.keySet()), params).stream().forEach(row -> { row.forEach((k,v) -> { if (!extract(v,nodes,rels)) { props.put(k,v); } }); }); return Stream.of(new VirtualGraph(name,nodes,rels,props)); } }
@Procedure public Stream<MapResult> parallel(@Name("fragment") String fragment, @Name("params") Map<String, Object> params, @Name("parallelizeOn") String key) { if (params == null) return run(fragment, params); if (key == null || !params.containsKey(key)) throw new RuntimeException("Can't parallelize on key " + key + " available keys " + params.keySet()); Object value = params.get(key); if (!(value instanceof Collection)) throw new RuntimeException("Can't parallelize a non collection " + key + " : " + value); final String statement = withParamMapping(fragment, params.keySet()); Collection<Object> coll = (Collection<Object>) value; return coll.parallelStream().flatMap((v) -> { terminationGuard.check(); Map<String, Object> parallelParams = new HashMap<>(params); parallelParams.replace(key, v); return db.execute(statement, parallelParams).stream().map(MapResult::new); }); /* params.entrySet().stream() .filter( e -> asCollection(e.getValue()).size() > 100) .map( (e) -> (Map.Entry<String,Collection>)(Map.Entry)e ) .max( (max,e) -> e.getValue().size() ) .map( (e) -> e.getValue().parallelStream().map( (v) -> { Map map = new HashMap<>(params); map.put(e.getKey(),as) })); return db.execute(statement,params).stream().map(MapResult::new); */ }
@Test public void testLoadXmlWithImport() { testCall(db, "call apoc.xml.import('file:src/test/resources/xml/humboldt_soemmering01_1791.TEI-P5.xml', {createNextWordRelationships: true}) yield node", row -> { assertNotNull(row.get("node")); }); testResult(db, "match (n) return labels(n)[0] as label, count(*) as count", result -> { final Map<String, Long> resultMap = result.stream().collect(Collectors.toMap(o -> (String)o.get("label"), o -> (Long)o.get("count"))); assertEquals(2l, (long)resultMap.get("XmlProcessingInstruction")); assertEquals(1l, (long)resultMap.get("XmlDocument")); assertEquals(1737l, (long)resultMap.get("XmlWord")); assertEquals(454l, (long)resultMap.get("XmlTag")); }); // no node more than one NEXT/NEXT_SIBLING testCallEmpty(db, "match (n) where size( (n)-[:NEXT]->() ) > 1 return n", null); testCallEmpty(db, "match (n) where size( (n)-[:NEXT_SIBLING]->() ) > 1 return n", null); // no node more than one IS_FIRST_CHILD / IS_LAST_CHILD testCallEmpty(db, "match (n) where size( (n)<-[:FIRST_CHILD_OF]-() ) > 1 return n", null); testCallEmpty(db, "match (n) where size( (n)<-[:LAST_CHILD_OF]-() ) > 1 return n", null); // NEXT_WORD relationship do connect all word nodes testResult(db, "match p=(:XmlDocument)-[:NEXT_WORD*]->(e:XmlWord) where not (e)-[:NEXT_WORD]->() return length(p) as len", result -> { Map<String, Object> r = Iterators.single(result); assertEquals(1737l, r.get("len")); }); }
Map<String, PropertyContainer> pcs = new HashMap<>(); db.execute("MATCH (n) RETURN n.id as id, n UNION ALL MATCH ()-[n]->() RETURN n.id as id, n") .stream().forEach(row -> pcs.put(row.get("id").toString(), (PropertyContainer)row.get("n")));
@Procedure(mode = Mode.READ) public Stream<NodeResult> listSchemas(@Name(value="searchString",defaultValue = "") String searchString) { Map<String,Object> params = new HashMap<>(); params.put("searchString",searchString); String cypher = (searchString.trim().equals("")?"MATCH (mns:_MapNs) RETURN mns ": "MATCH (mns:_MapNs) WHERE mns._ns CONTAINS $searchString OR mns._prefix CONTAINS $searchString RETURN mns "); return db.execute(cypher, params).stream().map(n -> (Node) n.get("mns")).map(NodeResult::new); }
@Procedure("algo.list") @Description("CALL algo.list - lists all algorithm procedures, their description and signature") public Stream<ListResult> list(@Name(value = "name", defaultValue = "") String name) { return db.execute(QUERY, singletonMap("name", name)).stream().map(ListResult::new); }
@Procedure("algo.list") @Description("CALL algo.list - lists all algorithm procedures, their description and signature") public Stream<ListResult> list(@Name(value = "name", defaultValue = "") String name) { return db.execute(QUERY, singletonMap("name", name)).stream().map(ListResult::new); }