let's say I have two nodes with one edge as :
country ---> has ---> school
where, edge "has" has property called "since".
If I created lookup index for nodes and edges + edge property.
g.createKeyIndex('country', Vertex.class)
g.createKeyIndex('school', Vertex.class)
g.createKeyIndex('has', Edge.class)
How to create index on edge property(since).Or while creating index in edge "has". properties get indexed. Is it ?
in Neo4j.property I set as :
# Autoindexing
# Enable auto-indexing for nodes, default is false
node_auto_indexing=true
# The node property keys to be auto-indexed, if enabled
node_keys_indexable=country, school
# Enable auto-indexing for relationships, default is false
relationship_auto_indexing=true
# The relationship property keys to be auto-indexed, if enabled
relationship_keys_indexable=since
but I don't want to create auto index through this property file but need in gremlin way before adding vertex/edges.
like in Titan way :
g.makeType().name('since').dataType(Date.class).unique(OUT).makePropertyKey()
how can it possible through simple neo4j + gremlin ?
am following :
http://www.tinkerpop.com/docs/javadocs/blueprints/2.1.0/com/tinkerpop/blueprints/KeyIndexableGraph.html#createKeyIndex(java.lang.String, java.lang.Class)
You are confusing the concept of indices a bit. Using createKeyIndex on Graph in this way:
g.createKeyIndex('has', Edge.class)
Is not creating an "indexed" edge label called "has". It is creating a index on a property called "has" that will lookup an Edge. If you want an index on "since" then simply do:
g.createKeyIndex('since', Edge.class)
That said, there is nothing I know of that exists in Neo4j that is analogous to vertex centric indices in Titan, so it's not as though your creation of a key index on "since" will allow Gremlin to take advantage of that index in a traversal outside of a simple key index lookup, like:
g.E('since', new Date())
Related
I want to delete all indexes that exist using cypher in a bulk can it be done? I am using neo4j 3.4.7.
DROP INDEX ON :Label(attributename)
Does it replace existing indexes if I create the same index in a later stage?
A quick way to drop all indexes and constraints is to use the APOC procedure apoc.schema.assert, as follows:
CALL apoc.schema.assert({},{},true) YIELD label, key
RETURN *
The procedure is mainly for ensuring that the DB has the indexes and constraints passed in the first 2 maps, but the third parameter determines whether any other indexes and constraints are dropped. In the above query, the first 2 maps are empty, so the end result is that all indexes and constraints are dropped.
For release 3.x your can to use built-in procedures Neo4j to delate what index your want. From web browser your can send Cipher query:
CALL db.indexes() - List all indexes in the database.
CALL db.index.fulltext.drop() -Drop the specified index.
or
CALL db.index.explicit.drop() - Remove an explicit index - YIELD type,name,config
All possible built-in procedures and parameter for last version here User management for Neo4j
old style do it with CIPHER :
DROP INDEX ON :labelOfNode(propertyOfNode)
CREATE INDEX ON :labelOfNode(propertyOfNode)
Using Neo4j.
I would like to add a integer number to values already existing in properties of several relationships that I call this way:
MATCH x=(()-[y]->(s:SOL{PRB:"Taking time"})) SET y.points=+2
But it doesn't add anything, just replace by 2 the value I want to incremente.
To achieve this use
SET y.points = y.points + 2
From your original question it looks like you were trying to use the Addition Assignment operator which exists in lots of languages (e.g. python, type/javascript, C#, etc.). However, in cypher += is a little different and is designed to do this in a way which allows you to add or update properties to or on entire nodes or relationships based on a mapping.
If you had a parameter like the below (copy this into the neo4j browser to create a param).
:param someMapping: {a:1, b:2}
The query below would create a property b on the node with value 2, and set the value of property a on that node to 1.
MATCH (n:SomeLabel) WHERE n.a = 0
SET n+= $someMapping
RETURN n
I am using neo4j.rb in my rails application.
I already have two nodes n1 and n2 retrieved from the database.
Now i need to check if they have a path between them, i was thinking of using cypher queries using Neo4j::Session.query
But since i already have the two nodes i do not want to retrieve them again inside the query,(does it affect performance?) is there a way to do it?
I know i can use query1 = n1.query_as(:node1) and use it as the node identifier but how can i introduce n2 within the same query object so that i can check connectivity between them.
I want something equivalent to the query
RETURN
CASE
WHEN node1-[*..6]-node2
THEN 'Connected within 6 nodes'
ELSE 'Not connected within 6'
END
Where i already have node1 and node2.
Is a way to do this and also can this be done without using the CYPHER DSL?
Here you go!
n1.query_as(:n1).match_nodes(n2: n2).match('n1-[*1..6]-n2').count
If you want to avoid the Cypher DSL I think you can do that with associations. As a starter example to traverse one level of relationships you can do this:
class N1Class
include Neo4j::ActiveNode
has_many :out, :test_association, type: :TEST_ASSOCIATION, model_class: :N2Class
end
n1.test_association.include?(n2)
That will test if they are directly connected via the test_association association. You can even specify false for your type to ignore the direction and false for the model_class to ignore the target labels.
To get the variable length you can do this:
n1.test_association(nil, nil, rel_length: 1..6).include?(n2)
I'm using Neo4j 2.0.0-M06. Just learning Cypher and reading the docs. In my mind this query would work, but I should be so lucky...
I'm importing tweets to a mysql-database, and from there importing them to neo4j. If a tweet is already existing in the Neo4j database, it should be updated.
My query:
MATCH (y:Tweet:Socialmedia) WHERE
HAS (y.tweet_id) AND y.tweet_id = '123'
CREATE UNIQUE (n:Tweet:Socialmedia {
body : 'This is a tweet', tweet_id : '123', tweet_userid : '321', tweet_username : 'example'
} )
Neo4j says: This pattern is not supported for CREATE UNIQUE
The database is currently empty on nodes with the matching labels, so there are no tweets what so ever in the Neo4j database.
What is the correct query?
You want to use MERGE for this query, along with a unique constraint.
CREATE CONSTRAINT on (t:Tweet) ASSERT t.tweet_id IS UNIQUE;
MERGE (t:Tweet {tweet_id:'123'})
ON CREATE
SET t:SocialMedia,
t.body = 'This is a tweet',
t.tweet_userid = '321',
t.tweet_username = 'example';
This will use an index to lookup the tweet by id, and do nothing if the tweet exists, otherwise it will set those properties.
I would like to point that one can use a combination of
CREATE CONSTRAINT and then a normal
CREATE (without UNIQUE)
This is for cases where one expects a unique node and wants to throw an exception if the node unexpectedly exists. (Far cheaper than looking for the node before creating it).
Also note that MERGE seems to take more CPU cycles than a CREATE. (It also takes more CPU cycles even if an exception is thrown)
An alternative scenario covering CREATE CONSTRAINT, CREATE and MERGE (though admittedly not the primary purpose of this post).
I'm new to Neo4j - just started playing with it yesterday evening.
I've notice all nodes are identified by an auto-incremented integer that is generated during node creation - is this always the case?
My dataset has natural string keys so I'd like to avoid having to map between the Neo4j assigned ids and my own. Is it possible to use string identifiers instead?
Think of the node-id as an implementation detail (like the rowid of relational databases, can be used to identify nodes but should not be relied on to be never reused).
You would add your natural keys as properties to the node and then index your nodes with the natural key (or enable auto-indexing for them).
E..g in the Java API:
Index<Node> idIndex = db.index().forNodes("identifiers");
Node n = db.createNode();
n.setProperty("id", "my-natural-key");
idIndex.add(n, "id",n.getProperty("id"));
// later
Node n = idIndex.get("id","my-natural-key").getSingle(); // node or null
With auto-indexer you would enable auto-indexing for your "id" field.
// via configuration
GraphDatabaseService db = new EmbeddedGraphDatabase("path/to/db",
MapUtils.stringMap(
Config.NODE_KEYS_INDEXABLE, "id", Config.NODE_AUTO_INDEXING, "true" ));
// programmatic (not persistent)
db.index().getNodeAutoIndexer().startAutoIndexingProperty( "id" );
// Nodes with property "id" will be automatically indexed at tx-commit
Node n = db.createNode();
n.setProperty("id", "my-natural-key");
// Usage
ReadableIndex<Node> autoIndex = db.index().getNodeAutoIndexer().getAutoIndex();
Node n = autoIndex.get("id","my-natural-key").getSingle();
See: http://docs.neo4j.org/chunked/milestone/auto-indexing.html
And: http://docs.neo4j.org/chunked/milestone/indexing.html
This should help:
Create the index to back automatic indexing during batch import We
know that if auto indexing is enabled in neo4j.properties, each node
that is created will be added to an index named node_auto_index. Now,
here’s the cool bit. If we add the original manual index (at the time
of batch import) and name it as node_auto_index and enable auto
indexing in neo4j, then the batch-inserted nodes will appear as if
auto-indexed. And from there on each time you create a node, the node
will get indexed as well.**
Source : Identifying nodes with Custom Keys
According Neo docs there should be automatic indexes in place
http://neo4j.com/docs/stable/query-schema-index.html
but there's still a lot of limitations
Beyond all answers still neo4j creates its own ids to work faster and serve better. Please make sure internal system does not conflict between ids then it will create nodes with same properties and shows in the system as empty nodes.
the ID's generated are default and cant be modified by users. user can use your string identifiers as a property for that node.