Launching a CREATE INDEX ON when the index already exists, in Neo4J - neo4j

What happens if you replay a CREATE INDEX ON command on a Neo4J database that already has this index.
Does Neo4J simply ignore that command?

The first time you will execute it, Neo4j will :
Create the index
Create a background job to populate it
As a query stat, tell you that an index is created
At the second attempt, you will have :
No error
No impact on the existed index
An empty stat for the query (ie. no new index created)
Cheers

the 2nd invocation of the create index will run, produce no error, but also not report the index alredy exists and in the end you will still only have 1 index

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.

What is the difference between .where(nil) and .all?

I have been using Product.all but a lot of code that I have been seeing is using Product.where(nil) when populating a variable. this site has an example that I found for using where(nil). I have searched through documentation and found where where(nil) replaced scoped but can't make heads or tails of what it does.
I believe there used to be a difference, but from Rails 4 there no longer is. This is because from Rails 4 .all returns a relation whereas it used to return an array. So previously:
Product.all
immediately fires a query to the database to return all records, which would get loaded into an array in memory. Basically you are telling Rails that you want the data NOW. See this question for more info.
Product.where(nil)
creates a query (actually an anonymous scope that returns an ActiveRecord:Relation).
The query will only execute when you try to access the data for it. Since it is a scope, you can chain other scopes (without hitting the database each time) and have the entire chain execute as one query when you access the data.
In the Justin Weiss article linked to in the question, we see this code:
def index
#products = Product.where(nil) # creates an anonymous scope
#products = #products.status(params[:status]) if params[:status].present?
#products = #products.location(params[:location]) if params[:location].present?
#products = #products.starts_with(params[:starts_with]) if params[:starts_with].present?
end
That code will execute one database call when the index method ends and returns the data.
But if you changed the first line to:
#products = Product.all
that query would execute immediately. Then the scopes are added, and another query would fire when index method ends. This is more inefficient.
EDIT
I believe the database call would actually happen when you first try to access some data in #products (not when the index method ends). Eg. if you did #products.first then the query would execute.

Can't view newly created records after database sequence reset

So I had some problems with my database. I have an import functionality which I used to import a few thousand records. Now I was developing locally (SQLite) and everything worked fine. I pushed my updates to heroku where I have a PostgreSQL database. I ran my import there and it appeared to work well too. Now, I'm trying to manually create an other record in that table and I kept getting the error that the unique ID was a duplicate. So, after some online searching I created this extension to active record:
def self.reset_pk_sequence
case ActiveRecord::Base.connection.adapter_name
when 'SQLite'
new_max = maximum(primary_key) || 0
update_seq_sql = "update sqlite_sequence set seq = #{new_max} where name = '#{table_name}';"
ActiveRecord::Base.connection.execute(update_seq_sql)
when 'PostgreSQL'
ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
else
raise "Task not implemented for this DB adapter"
end
end
I ran it on my table, and the ID is now counting up from where it should (3000 something instead of 1,2,3, etc).
My problem now is that I am able to create new records in my table, and I see them in my index page. However, when I try to open that specific record, I get this error:
The page you were looking for doesn't exist.
You may have mistyped the address or the page may have moved.
The link from my index is just to the ID of the record. When I check if this ID exists in the console, I'm perfectly able to find the record. What's going wrong here?
I figured it out. I had some empty associations that I was trying to display in the view. The error threw me off since it appeared like something was wrong with my record.

Neo4j Index not available

I try to create an index in Neo4j, but it seems like it is not working. I insert data with the following codes snippet.
create index on :`Person`(`name`)
create (_0:`Person` {`name`:"Andres"})
create (_1:`Person` {`name`:"Mark"})
create _0-[:`KNOWS`]->_1
The code here works fine. But when I try to fetch data with cypher command
START n=node:name(name= 'Bob')
RETURN n
I've got an error
Index `name` does not exist
Neo.ClientError.Schema.NoSuchIndex
But as you can see above, I declare an index name. What do I query wrong?
either you must use automatic index - http://docs.neo4j.org/chunked/milestone/auto-indexing.html - where you first specify in the neo4j config file which parameters would be indexed (than start/restart the server)
or when using manual indexing - http://docs.neo4j.org/chunked/milestone/indexing-add.html - you must include each new node into the index manualy like this:
MATCH (n:Person)
USING INDEX n:Person(name)
WHERE n.name = 'Bob'
RETURN n
view also neo4j cypher : unable to create and use an index

Wrong data returned from elasticsearch after recreate the index

for testing and development reasons we reindex our data from a rails app by deleting an index and recreate with mapping and import existing documents.
But after recreating the index, elasticsearch returns other results than expected and before recreating. If we restart the elasticsearch instance, the results as expected.
This is how we recreate the index.
Tire.index indexname do
delete
create _mappings
import _objects
refresh
end
We also checked the search query directly via curl on elastic search, but we got not the expected result. After restarting the elastic search daemon, same query returns expected data.
What have to be done or what is expected of an elasticsearch instance to return correct data after recreating an index with the same name without restarting? We also tried creating new indexes with timestamp names and aliasing the index name to these index, but with same results.
thanks in advance

Resources