@Description( "Query the given fulltext index. Returns the matching nodes and their lucene query score, ordered by score." ) @Procedure( name = "db.index.fulltext.queryNodes", mode = READ ) public Stream<NodeOutput> queryFulltextForNodes( @Name( "indexName" ) String name, @Name( "queryString" ) String query ) throws ParseException, IndexNotFoundKernelException, IOException { IndexReference indexReference = getValidIndexReference( name ); awaitOnline( indexReference ); EntityType entityType = indexReference.schema().entityType(); if ( entityType != EntityType.NODE ) { throw new IllegalArgumentException( "The '" + name + "' index (" + indexReference + ") is an index on " + entityType + ", so it cannot be queried for nodes." ); } ScoreEntityIterator resultIterator = accessor.query( tx, name, query ); return resultIterator.stream() .map( result -> NodeOutput.forExistingEntityOrNull( db, result ) ) .filter( Objects::nonNull ); }
public Optional<DefaultParameterValue> defaultValue( Name parameter ) throws ProcedureException { String defaultValue = parameter.defaultValue(); if ( defaultValue.equals( Name.DEFAULT_VALUE ) ) { return Optional.empty(); } else { try { return Optional.of( parser.apply( defaultValue ) ); } catch ( Exception e ) { throw new ProcedureException( Status.Procedure.ProcedureRegistrationFailed, "Default value `%s` could not be parsed as a %s", parameter.defaultValue(), javaClass.getSimpleName() ); } } }
@Procedure @Description("apoc.warmup.run(loadProperties=false,loadDynamicProperties=false,loadIndexes=false) - quickly loads all nodes and rels into memory by skipping one page at a time") public Stream<WarmupResult> run(@Name(value = "loadProperties", defaultValue = "false") boolean loadProperties, @Name(value = "loadDynamicProperties", defaultValue = "false") boolean loadDynamicProperties, @Name(value = "loadIndexes", defaultValue = "false") boolean loadIndexes) throws IOException { PageCache pageCache = db.getDependencyResolver().resolveDependency(PageCache.class); .filter(pF -> { String name = pF.file().getName(); if (isSchema(pF.file()) && !loadIndexes) return false; return true; }) .map((pagedFile -> { File file = pagedFile.file(); boolean index = isSchema(file); pageCache.reportEvents(); })).collect(Collectors.toMap(r -> r.file, r -> r));
@Admin @Description( "List the currently active config of Neo4j." ) @Procedure( name = "dbms.listConfig", mode = DBMS ) public Stream<ConfigResult> listConfig( @Name( value = "searchString", defaultValue = "" ) String searchString ) { Config config = graph.getDependencyResolver().resolveDependency( Config.class ); String lowerCasedSearchString = searchString.toLowerCase(); return config.getConfigValues().values().stream() .filter( c -> !c.internal() ) .filter( c -> c.name().toLowerCase().contains( lowerCasedSearchString ) ) .map( ConfigResult::new ) .sorted( Comparator.comparing( c -> c.name ) ); }
@Procedure("apoc.schema.properties.distinctCount") @Description("apoc.schema.properties.distinctCount([label], [key]) YIELD label, key, value, count - quickly returns all distinct values and counts for a given key") public Stream<PropertyValueCount> distinctCount(@Name(value = "label", defaultValue = "") String labelName, @Name(value = "key", defaultValue = "") String keyName) throws SchemaRuleNotFoundException, IndexNotFoundKernelException, IOException { Iterable<IndexDefinition> labels = (labelName.isEmpty()) ? db.schema().getIndexes() : db.schema().getIndexes(Label.label(labelName)); return StreamSupport.stream(labels.spliterator(), false).filter(i -> keyName.isEmpty() || isKeyIndexed(i, keyName)).flatMap( index -> { Iterable<String> keys = keyName.isEmpty() ? index.getPropertyKeys() : Collections.singletonList(keyName); return StreamSupport.stream(keys.spliterator(), false).flatMap(key -> { String label = index.getLabel().name(); return distinctTermsCount(label, key). entrySet().stream().map(e -> new PropertyValueCount(label, key, e.getKey(), e.getValue())); }); } ); }
@Procedure @Description("apoc.text.phonetic(value) yield value - Compute the US_ENGLISH phonetic soundex encoding of all words of the text value which can be a single string or a list of strings") public Stream<StringResult> phonetic(final @Name("value") Object value) { Stream<Object> stream = value instanceof Iterable ? StreamSupport.stream(((Iterable) value).spliterator(), false) : Stream.of(value); return stream.map(str -> str == null ? StringResult.EMPTY : new StringResult(Stream.of(str.toString().split("\\W+")) .map(US_ENGLISH::soundex).reduce("", (a, s)->a+s))); }
@Procedure( "spatial.pointGeometry" ) public Stream<GeometryResult> spatialPointGeometry( @Name( "longitude" ) double longitude, @Name( "latitude" ) double latitude ) { Geometry geometry = makeFakePointAsGeometry( longitude, latitude, makeWGS84() ); return Stream.of( new GeometryResult( geometry ) ); } }
@Deprecated @Description( "Add a node to an explicit index based on a specified key and value" ) @Procedure( name = "db.index.explicit.addNode", mode = WRITE, deprecatedBy = EXPLICIT_INDEX_DEPRECATION ) public Stream<BooleanResult> nodeManualIndexAdd( @Name( "indexName" ) String explicitIndexName, @Name( "node" ) Node node, @Name( "key" ) String key, @Name( "value" ) Object value ) { graphDatabaseAPI.index().forNodes( explicitIndexName ).add( node, key, value ); // Failures will be expressed as exceptions before the return return Stream.of( new BooleanResult( Boolean.TRUE ) ); }
@Procedure public Stream<DegreeStats.Result> degrees(@Name(value = "types", defaultValue = "") String types) { List<DegreeStats> stats = prepareStats(types); MultiThreadedGlobalGraphOperations.forAllNodes(db, Pools.DEFAULT, BATCHSIZE, (ktx,nodeCursor)-> stats.forEach((s) -> s.computeDegree(nodeCursor, ktx.cursors())) ); return stats.stream().map(DegreeStats::done); }
@Admin @Description( "Retrieve all available statistical data about the current database, in an anonymized form." ) @Procedure( name = "db.stats.retrieveAllAnonymized", mode = Mode.READ ) public Stream<RetrieveResult> retrieveAllAnonymized( @Name( value = "graphToken" ) String graphToken, @Name( value = "config", defaultValue = "" ) Map<String, Object> config ) throws IndexNotFoundKernelException, TransactionFailureException, InvalidArgumentsException { Map<String, Object> metaData = new HashMap<>(); metaData.put( "graphToken", graphToken ); metaData.put( "retrieveTime", ZonedDateTime.now() ); TokensSection.putTokenCounts( metaData, dataCollector.kernel ); Stream<RetrieveResult> meta = Stream.of( new RetrieveResult( "META", metaData ) ); return Stream.of( meta, GraphCountsSection.retrieve( dataCollector.kernel, Anonymizer.IDS ), QueriesSection.retrieve( dataCollector.queryCollector.doGetData(), new IdAnonymizer( transaction.tokenRead() ), RetrieveConfig.of( config ).maxInvocations ) ).flatMap( x -> x ); }
@Deprecated @Description( "Get node from explicit automatic index. Replaces `START n=node:node_auto_index(key = 'A')`" ) @Procedure( name = "db.index.explicit.auto.seekNodes", mode = READ, deprecatedBy = EXPLICIT_INDEX_DEPRECATION ) public Stream<NodeResult> nodeAutoIndexSeek( @Name( "key" ) String key, @Name( "value" ) Object value ) { try ( Statement ignore = tx.acquireStatement() ) { NodeExplicitIndexCursor cursor = tx.cursors().allocateNodeExplicitIndexCursor(); tx.indexRead().nodeExplicitIndexLookup( cursor, "node_auto_index", key, value ); return toStream( cursor, id -> new NodeResult( graphDatabaseAPI.getNodeById( id ) ) ); } catch ( KernelException e ) { // auto index will not exist if no nodes have been added that match the auto-index rules return Stream.empty(); } }
@Description( "Attaches a map of data to the transaction. The data will be printed when listing queries, and " + "inserted into the query log." ) @Procedure( name = "dbms.setTXMetaData", mode = DBMS ) public void setTXMetaData( @Name( value = "data" ) Map<String,Object> data ) { securityContext.assertCredentialsNotExpired(); int totalCharSize = data.entrySet().stream() .mapToInt( e -> e.getKey().length() + e.getValue().toString().length() ) .sum(); if ( totalCharSize >= HARD_CHAR_LIMIT ) { throw new IllegalArgumentException( format( "Invalid transaction meta-data, expected the total number of chars for " + "keys and values to be less than %d, got %d", HARD_CHAR_LIMIT, totalCharSize ) ); } try ( Statement statement = getCurrentTx().acquireStatement() ) { statement.queryRegistration().setMetaData( data ); } }
@Description( "Create a new user." ) @Procedure( name = "dbms.security.createUser", mode = DBMS ) public void createUser( @Name( "username" ) String username, @Name( "password" ) String password, @Name( value = "requirePasswordChange", defaultValue = "true" ) boolean requirePasswordChange ) throws InvalidArgumentsException, IOException { // TODO: Deprecate this and create a new procedure that takes password as a byte[] securityContext.assertCredentialsNotExpired(); userManager.newUser( username, password != null ? UTF8.encode( password ) : null, requirePasswordChange ); }
@Description( "Create a RelationshipType" ) @Procedure( name = "db.createRelationshipType", mode = WRITE ) public void createRelationshipType( @Name( "newRelationshipType" ) String newRelationshipType ) throws IllegalTokenNameException { tx.tokenWrite().relationshipTypeGetOrCreateForName( newRelationshipType ); }
@Description( "Drop the specified index." ) @Procedure( name = "db.index.fulltext.drop", mode = SCHEMA ) public void drop( @Name( "indexName" ) String name ) throws InvalidTransactionTypeKernelException, SchemaKernelException { IndexReference indexReference = getValidIndexReference( name ); tx.schemaWrite().indexDrop( indexReference ); }
@UserFunction @Description("apoc.nodes.isDense(node) - returns true if it is a dense node") public boolean isDense(@Name("node") Node node) { try (NodeCursor nodeCursor = ktx.cursors().allocateNodeCursor()) { final long id = node.getId(); ktx.dataRead().singleNode(id, nodeCursor); if (nodeCursor.next()) { return nodeCursor.isDense(); } else { throw new IllegalArgumentException("node with id " + id + " does not exist."); } } }
@Description( "Wait for all indexes to come online (for example: CALL db.awaitIndexes(\"500\"))." ) @Procedure( name = "db.awaitIndexes", mode = READ ) public void awaitIndexes( @Name( value = "timeOutSeconds", defaultValue = "300" ) long timeout ) { graphDatabaseAPI.schema().awaitIndexesOnline( timeout, TimeUnit.SECONDS ); }
@Procedure @Deprecated @Description("just use a cypher query with a range predicate on an indexed field and wait for index backed order by in 3.5") public Stream<NodeResult> orderedByText(@Name("label") String label, @Name("key") String key, @Name("operator") String operator, @Name("value") String value, @Name("relevance") boolean relevance, @Name("limit") long limit) throws SchemaRuleNotFoundException, IndexNotFoundKernelException, DuplicateSchemaRuleException { SortedIndexReader sortedIndexReader = getSortedIndexReader(label, key, limit, getSort(value,value,relevance)); PrimitiveLongIterator it = queryForString(sortedIndexReader, operator, value); return Util.toLongStream(it).mapToObj(id -> new NodeResult(db.getNodeById(id))); }