Neo4j How to write Dot in Properties or Relations - neo4j

I have a problem that is specific. After I load the triples from RDF file thanks to plugin, some properties or relations are look like:
Relation Example ===> [:Country.city]
Property Example ==> city.name
there is a dot in property name and relation name. They can be created thanks to plugin There is no problem. But when i write query from this 127.0.0.1:7474 interface, i cant write dot '.' in property name or relation name. But the property name is contain dot. I need to write it .
Result : Syntax error invalid input '.'
How can I write correctly this property or relation name?

Escape the entire relationship type or property name with backticks.
MATCH (x)-[:`Country.city`]->(y) RETURN x,y
...
MATCH (x)-[:Contain]->(y) WHERE x.`city.name`="London" RETURN x,y

Related

Not able to create a node with special characters "-" in neo4j

I am trying to create a node in neo4j(version 3.2.3). Below is the cypher query,
MERGE (`source-real-address`:SOURCE {Source:{`source-real-address`}})
I found in forums to create a node with special characters we should use
backticks `
in the query. But I couldn't able to create a node with backticks. No error were thrown in the logs.
Could you please help me to resolve this?
Please correct me if I am doing anything wrong in the cypher query. I am started
to understand neo4j cypher query language.
Note:- I am sending data to neo4j from graylog with the help of neo4j output plugin. I could able to create node without special character fields.
The syntax {Source:{`source-real-address`}}) means that you are trying to use a param named source-real-address as the value of the property Source. If this is your goal, you can set a param in the Neo4j Browser for test purposes with :params {"source-real-address":"Some value"}. If not, you can remove the extra { and } in the value and use "" instead of backticks, like this:
MERGE (source-real-address:SOURCE {Source:"source-real-address"})
Remeber that the value of a property should be Boolean, Integer, Float or String.
In Cypher backticks are used to create relationships, labels and variable names with special chars (not for property values).
Use the CREATE command to create Node with special characters
see this also: https://neo4j.com/docs/cypher-manual/current/syntax/naming/

Neo4j-Cypher Warning: The provided property key is not in the database but the variable is being declared above

I really liked the example and the code of this link Neo4j: Display all connected nodes and their parent in tree-like graph
but the thing is that as I managed it to my database it thrown me some warnings.
This feature is deprecated and will be removed in future versions.
Using 'length' on anything that is not a path is deprecated, please use 'size' instead
WITH REDUCE(s=[], i IN RANGE(0, LENGTH(np)-2, 1) | s + {p:np[i], c:np[i+1]}) AS cpairs
^
The provided property key is not in the database
One of the property names in your query is not available in the database, make sure you didn't misspell it or that the label is available when you run this statement in your application (the missing property name is is: p)
RETURN ps.p, "parent of", ps.c;
^
The provided property key is not in the database
One of the property names in your query is not available in the database, make sure you didn't misspell it or that the label is available when you run this statement in your application (the missing property name is is: c)
RETURN ps.p, "parent of", ps.c;
^
I fixed the first one by substituting the length with size...
What about the rest? since they're declared in previous lines?
Here's my version of code:
MATCH path=(n:Atomo {name:'Dema'})<-[:DAD_OF*]-()
WITH NODES(path) AS np
WITH REDUCE(s=[], i IN RANGE(0, SIZE(np)-2, 1) | s + {p:np[i], c:np[i+1]}) AS cpairs
UNWIND cpairs AS pairs
WITH DISTINCT pairs AS ps
RETURN ps.p, "parent of", ps.c;

Cypher query with literal map syntax & dynamic keys

I'd like to make a cypher query that generates a specific json output. Part of this output includes an object with a dynamic amount of keys relative to the children of a parent node:
{
...
"parent_keystring" : {
child_node_one.name : child_node_one.foo
child_node_two.name : child_node_two.foo
child_node_three.name : child_node_three.foo
child_node_four.name : child_node_four.foo
child_node_five.name : child_node_five.foo
}
}
I've tried to create a cypher query but I do not believe I am close to achieving the desired output mentioned above:
MATCH (n)-[relone:SPECIFIC_RELATIONSHIP]->(child_node)
WHERE n.id='839930493049039430'
RETURN n.id AS id,
n.name AS name,
labels(n)[0] AS type,
{
COLLECT({
child.name : children.foo
}) AS rel_two_representation
} AS parent_keystring
I had planned for children.foo to be a count of how many occurrences of each particular relationship/child of the parent. Is there a way to make use of the reduce function? Where a report would generate based on analyzing the array proposed below? ie report would be a json object where each key is a distinct RELATIONSHIP and the property value would be the amount of times that relationship stems from the parent node?
Thank you greatly in advance for guidance you can offer.
I'm not sure that Cypher will let you use a variable to determine an object's key. Would using an Array work for you?
COLLECT([child.name, children.foo]) AS rel_two_representation
I think, Neo4j Server API output by itself should be considered as any database output (like MySQL). Even if it is possible to achieve, with default functionality, desired output - it is not natural way for database.
Probably you should look into creating your own server plugin. This allows you to implement any custom logic, with desired output.

Filter by defining concrete entity as the operand, i.e. not using a primitive value

In the examples I've checked, the operand is always a primitive value, like:
http://host/service/Products?$filter=MainIngredient eq 'Milk'
what if the MainIngredient property is an entity, and I want to reference exactly this entity? Abstracting other cases, that would be something like
http://host/service/Products?$filter=MainIngredient eq Ingredient('770d5720-9ae8-11e3-a5e2-0800200c9a66)
...or isn't the filter not the correct instrument to use, at all?
I think you mean that MainIngredient is the name of a navigation property that points to a single entity of type Ingredient, such as:
http://host/service/Products(1234)/MainIngredient
If this is the case, and assuming that the key of Ingredient is called "ID" then I think the correct form of URL for what you want to do is:
http://host/service/Products?$filter=MainIngredient/ID eq guid'770d5720-9ae8-11e3-a5e2-0800200c9a66'
That would return only products that are linked, via MainIngredient, to the Ingredient with the ID you gave in the question.

How to match ets:match against a record in Erlang?

I have heard that specifying records through tuples in the code is a bad practice: I should always use record fields (#record_name{record_field = something}) instead of plain tuples {record_name, value1, value2, something}.
But how do I match the record against an ETS table? If I have a table with records, I can only match with the following:
ets:match(Table, {$1,$2,$3,something}
It is obvious that once I add some new fields to the record definition this pattern match will stop working.
Instead, I would like to use something like this:
ets:match(Table, #record_name{record_field=something})
Unfortunately, it returns an empty list.
The cause of your problem is what the unspecified fields are set to when you do a #record_name{record_field=something}. This is the syntax for creating a record, here you are creating a record/tuple which ETS will interpret as a pattern. When you create a record then all the unspecified fields will get their default values, either ones defined in the record definition or the default default value undefined.
So if you want to give fields specific values then you must explicitly do this in the record, for example #record_name{f1='$1',f2='$2',record_field=something}. Often when using records and ets you want to set all the unspecified fields to '_', the "don't care variable" for ets matching. There is a special syntax for this using the special, and otherwise illegal, field name _. For example #record_name{record_field=something,_='_'}.
Note that in your example you have set the the record name element in the tuple to '$1'. The tuple representing a record always has the record name as the first element. This means that when you create the ets table you should set the key position with {keypos,Pos} to something other than the default 1 otherwise there won't be any indexing and worse if you have a table of type 'set' or 'ordered_set' you will only get 1 element in the table. To get the index of a record field you can use the syntax #Record.Field, in your example #record_name.record_field.
Try using
ets:match(Table, #record_name{record_field=something, _='_'})
See this for explanation.
Format you are looking for is #record_name{record_field=something, _ = '_'}
http://www.erlang.org/doc/man/ets.html#match-2
http://www.erlang.org/doc/programming_examples/records.html (see 1.3 Creating a record)

Resources