How to find a list of index using Cypher - neo4j

I've created an INDEX using cypher for my :Person label, but I cannot find any way of printing out a list of indexes or constraints available to my Neo4j system.
Is this something that is doable via Cypher?

As Eve pointed out, you can get labels by calling CALL.Labels(). To get indexes just do:
CALL db.indexes()
Also if you do CALL db. in your neo4j browser you will see all the functions available.

In browser you can use :schema or schema in the shell to print out all the indexes and constraints.

Nope. There's not even a way to list labels:
https://github.com/neo4j/neo4j/issues/1287
There are some REST calls for this, and the undocumented schema command in neo4j-shell is handy.
Edit: Update for 3.0 with the new stored procedures!
CALL db.labels()

(Applicable to neo4j version 2.3.1 or later)
To get indexes via REST use this:
curl http://localhost:7474/db/data/schema/index/
In the neo4j console you can run the :schema command to get all indexes & constraints.

Related

Neo4j: How to call "CREATE INDEX" only if not exists

The CREATE INDEX <indexName> command is not idempotent and will cause an error if the given index already exists. I'm new to neo4j, and can't find a predicate that avoids this error. I've tried various permutations of ANY(...), and they all barf at "db.indexes()".
Since CREATE INDEX ... fails if the index exists and DROP INDEX ... fails if it doesn't, I don't know how to write a .cypher file that creates the index only if needed.
A short form might be something like CREATE INDEX indexName FOR (c:SomeLabel) ON (c.someProperty) IF NOT EXISTS, but of course that short form doesn't exist.
Is there some way to do this with a predicate, subquery or some such expression?
As of Neo4j 4.1.3, a new index creation syntax has been introduced to do just that
CREATE INDEX myIndex IF NOT EXISTS FOR (t:Test) ON (t.id)
Indexes for search performance
You can use the apoc.schema.node.indexExists function to check whether an index exists before creating it.
For example, this query will create the :Foo(id) index if it does not already exist:
WITH 1 AS ignored
WHERE NOT apoc.schema.node.indexExists('Foo', ['id'])
CALL db.createIndex('index_name', ['Foo'], ['id'], 'native-btree-1.0') YIELD name, labels, properties
RETURN name, labels, properties
For some reason, the Cypher planner currently is not able to parse the normal CREATE INDEX index_name ... syntax after the above WHERE clause, so this query uses the db.createIndex procedure instead.
There is also a much more powerful APOC procedure, apoc.schema.assert, but it may be overkill for your requirements.
By default, the command is ignored if the index exists.
Can you test the following?
CREATE (n:Car {id: 1});
Added 1 label, created 1 node, set 1 property, completed after 23 ms.
CREATE INDEX ON :Car (id);
1st execution: Added 1 index, completed after 6 ms.
2nd execution : (no changes, no records)
I tried both suggestions, and neither solves my issue. I don't have time to discover, through trial-and-error, how to install APOC in my environment.
The first line of mbh86's answer is inaccurate, at least in my system. The command is not ignored, it fails with an error. So if anything else is in the same cypher script, it will fail.
The best I can do is apparently to wrap the CREATE INDEX in a command-line string, run that string from either a bash or python script, run it, and check the return code from the calling program.
I appreciate the effort of both commentators, and I didn't want to leave either hanging.

how to properly create a between clause on mongo mapper

I'm trying to create a query like this
User.find_each(created_at: [1.day.ago.utc, Date.now]) do |user|
but that didn't worked. Always return 0 users, but I do have users created in the 1 day timeframe. I believe I'm doing this query wrong, but the mongo mapper documentation says nothing about this.
Any ideas?
Activate the profiling with db.setProfilingLevel(2).
Rerun your code.
Get the query you sent to MongoDB in the system.profile collection.
Run this query in the mongoshell to check what's wrong.
Update your code to send the command you want.

How to access dynamic attribute 'geo_near_distance' with Mongoid

I am using Mongoid 3.1.6 with Rails 4. I need to find all the objects 'near' a certain co-ordinate. For each result from the search, I will need to display the distance from the search co-orodinate. According to Mongoid Documentation
...each instantiated document from a $geoNear query will get a special
dynamic attribute geo_near_distance that will be available as long as
the document is in memory.
But I am not able to access the Object.geo_near_distance
My query inside controller...
#objects = Object.geo_near([-118.4451, 34.0633]).max_distance(10)
Edit#1
Some additional details
If the use the following query in MongoDB
db.runCommand( { geoNear: "objects",
near: [ -73.95269,40.77578],
spherical: true
})
I see an array of 100 elements. Each element has 2 attributes. The first one, 'dis' has values like '0.000123' (Note: this is not in Km or Mile) and the second attribute is the result Object itself.
Now I have changed the query to Mongoid to...
#objects = Object.geo_near([-118.4451, 34.0633]).spherical.max_distance(10)
still no result.
Thanks in advance for your help.
After more than 2 years, the issue ticket is still open on mongodb jira tracker.
The quick fix is not use the hash notation instead of the dot notation to access the attribute:
Instead of
Object.geo_near_distance
Use
Object['geo_near_distance']
Tested on mongoid 6
Are you accessing the field while you are iterating the documents? You can see by the specs that this field is in fact there when the document is in memory and is being part of the iteration of the criteria result.
https://github.com/mongoid/mongoid/blob/master/spec/mongoid/contextual/geo_near_spec.rb#L167

Neo4jShell Facebook data import, cannot create relationships

I followed the following post to test facebook friends of friends in Neo4j 2.0.1
http://blog.neo4j.org/2013/06/fun-with-facebook-in-neo4j_19.html
I am able to create the nodes successfully.. Auto Indexing is enabled
Here is the create node statement - create (n{name:'User 123', type:'Facebook'});
This works fine
When I create the relationships, I am getting this notification: "Nothing was created and No data Returned"
Here is the create Relationship statement
start n1=node:node_auto_index(name='User 123'),n2=node:node_auto_index(name='User XYZ') CREATE n1-[:IS_A_FRIEND_OF]->n2;
Any help is very much appreciated. I am new to neo4j and trying to get my hands dirty by learning some stuff.
Neo4j 2.0 has a new feature called schema indexes. For most use cases it's beneficial to use schema indexing instead of autoindexing.
For your example, I'd move the value of the type property to become a label.
First, create the index for property name based on label Facebook:
CREATE INDEX ON :Facebook(name)
The CREATE looks like:
CREATE (n:Facebook {name:'User 123'})
For creating the relationships use:
MATCH (n1:Facebook {name:'User 123'}),n2=(n2:Facebook {name:'User XYZ'})
CREATE n1-[:IS_A_FRIEND_OF]->n2
You might also look into Neo4j 2.0's new MERGE statement.

Find the list of list of indexed keys in mongomapper

I am working on a rails app with mongodb and mongomapper. I would like to index few keys in the database. This is first project for me on mongo.
The keys i want to index i can specify like this
User.ensure_index(:email)
as described here
My question is, do i need to call this manually(may be wrapping it in a method) to make the indexing really happening?
And how can i find the list of keys which are having indices?
Here are the answers to my questions
Do i need to call this manually(may be wrapping it in a method) to make the indexing really happening?
Yes, we have to manually call the ensure_index method on Model. So we can wrap that in a method and can call from the console or even a rake task.
def self.create_index
self.ensure_index(:email)
self.ensure_index(:first_name)
self.ensure_index(:last_name)
true
end
then from console
User.create_index
you can check what keys are indexed using mongo's getIndexes() method
like this
mongo #=> enter the mongo console
show dbs #=> see the list of available dbs
use my_database #=> switch to your database
db.table_name.getIndexes() #=> replace table_name with your's
and that's it, you can see the list of indices on your table
Thanks!

Resources