How to keep objects in node Neo4j - neo4j

I have array of objects with this structure
[{
name:'here is name, which can have punctuation marks ',
value: 'here will be text '
},
{
name:'here is name, which can have punctuation marks ',
value: 'here will be text '
}]
I am trying to find the best way to keep it in neo4j node. Since later I am going to search, filter ... on this data I don't want to keep hole object as string. Creating property by name object.name is not possible because I have punctuation marks. The ideal way would be to keep it as property, because I am going to use this data as property of node, but removing punctuation marks from name is not an option too.
Probably I could keep them in array
['here is the name', ' and the second element of array is the text']
In this case the problem will be to give correct name to the property, which will have this array.
Another option could be to keep all data in list like this
tabs: ['first name - first value', ' second name - second value']
but to search later I will need to use regex inside the list. this doesn't seem flexible.
So what would be the best way ?
Thank you in advance!

You have few possibilities in terms of storing objects in the Neo4j database.
You can turn your JSON object into a string and save it as a property and later you can use APOC procedures for conversation to/from (using these procedures can help you with filtering or sorting on these).
You can create the helper nodes and treat each element of a list as a separate node (I think this is the suggested approach).
Worth to mention, that you can link your nodes to keep the order or just connect them directly if you don't really care about order.

The simplest solution is to use backticks as mentioned in neo4j community forum by Andreas Kollegger
CREATE ({`here is "name", which has punctuation marks!`:"here will be text"})
for more complex cases Giuseppe Villani suggested better solution
CALL apoc.create.nodes(["MyLabel"], [{
`name.with.dots`:'here is name, which can have punctuation marks .',
value: 'here will be text '
},
{
name:'here is name, which can have punctuation marks ',
value: 'here will be text '
}]) yield node
return node
to create a Node with a label ("MyLabel" in this case), so that you can have every data you need in a specific label (possibly to be indexed and/or connect with other entities)

Related

Delphi - How to filter a ADOTable for strings that contain a substring

noob here. The question once again says it all, :).
I have a ADOTable that is connected to a dbgrid and .mdb file. I want to filter my table field "OwnerName" for all instances of a string that contain another substring and display them on the dbGrid. Each record has this string field "OwnerName". How do I do this?
Ex:
substring: 'J'
Strings: 'Jannie', Johanna, Ko-Ja etc..
If possible I also want to be able to filter for string that not only start with that exact wubstring, but contain it later in as well, as with my stupid example: Ko-Ja.
Regards!!!
The are just two properties you have to set: Filter and Filtered. In the first set the filter condition (similar to SQL) and the second is a boolean stating whether to apply the filter or not.
Example:
YourADOTable.Filter := 'OwnerName LIKE ''%J%''';
YourADOTable.Filtered := True;
The %s in '%J%' means 'anything'.. so this way you are filtering for records which has in the OwnerName the text 'anything followed by a J and then anything again'.
Once you apply the filter, the dbGrid updates automatically.
You can find more info on Filter String at:
http://docwiki.embarcadero.com/Libraries/Sydney/en/Data.DB.TDataSet.Filter

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/

How to set all relationships of a certain type -- replacing the old ones if necessary -- in Neo4j?

I have a node id for an event, and list of node ids for users that are hosting the event. I want to update these (:USER)-[:HOSTS]->(:EVENT) relationships. I dont just want to add the new ones, I want to remove the old ones as well.
NOTE: this is coffeescript syntax where #{} is string interpolation, and str() will escape any characters for me.
Right now I'm querying all the hosts:
MATCH (u:USER)-[:HOSTS]->(:EVENT {id:#{str(eventId)}})
RETURN u.id
Then I'm determining which hosts are new and need to be added and which ones are old and need to be removed. For the old ones, I remove them
MATCH (:HOST {id:#{str(host.id)}})-[h:HOSTS]->(:EVENT {id:#{str(eventId)}})
DELETE h
And for the new ones, I add them:
MATCH (e:EVENT {id: #{str(eventId)}})
MERGE (u:USER {id:#{str(id)}})
SET u.name =#{str(name)}
MERGE (u)-[:HOSTS]->(e)
So my question is, can I do this more efficiently all in one query? I want want to set the new relationships, getting rid of any previous relationships that arent in the new set.
If I understand your question correctly, you can achieve your objective in a single query by introducing WITH and FOREACH. On a sample graph created by
CREATE (_1:User { name:"Peter" }),(_2:User { name:"Paul" }),(_3:User { name:"Mary" })
CREATE (_4:Event { name:"End of the world" })
CREATE _1-[:HOSTS]->_4, _2-[:HOSTS]->_4
you can remove the no longer relevant hosts, and add the new hosts, as such
WITH ["Peter", "Mary"] AS hosts, "End of the world" AS eventId
MATCH (event:Event { name:eventId })<-[r:HOSTS]-(u:User)
WHERE NOT u.name IN hosts
DELETE r
WITH COLLECT(u.name) AS oldHosts, hosts, event
WITH FILTER(h IN hosts
WHERE NOT h IN oldHosts) AS newHosts, event, oldHosts
FOREACH (n IN newHosts |
MERGE (nh:User { name:n })
MERGE nh-[:HOSTS]->event
)
I have made some assumptions, at least including
The new host (:User) of the event may already exists, therefore MERGE (nh:User { name:n }) and not CREATE.
The old [:HOSTS]s should be disconnected from the event, but not removed from the database.
Your coffee script stuff can be translated into parameters, and you can translate my pseudo-parameters into parameters. In my sample query I simulate parameters with the first line, but you may need to adapt the syntax according to how you actually pass the parameters to the query (I can't turn Coffee into Cypher).
Click here to test the query. Change the contents of the hosts array to ["Peter", "Paul"], or to ["Peter", "Dragon"], or whatever value makes sense to you, and rerun the query to see how it works. I've used name rather than id to catch the nodes, and again, I've simulated parameters, but you might be able to translate the query to the context from which you want to execute it.
Edit:
Re comment, if you want the query to also match events that don't have any hosts you need to make the -[:HOSTS]- part of the pattern optional. Do so by braking the MATCH clause in two:
MATCH (event:Event { name:eventId })
OPTIONAL MATCH event<-[r:HOSTS]-(u:User)
The rest of the query is the same.

Suppress delimiters in Ruby's String#split

I'm importing data from old spreadsheets into a database using rails.
I have one column that contains a list on each row, that are sometimes formatted as
first, second
and other times like this
third and fourth
So I wanted to split up this string into an array, delimiting either with a comma or with the word "and". I tried
my_string.split /\s?(\,|and)\s?/
Unfortunately, as the docs say:
If pattern contains groups, the respective matches will be returned in the array as well.
Which means that I get back an array that looks like
[
[0] "first"
[1] ", "
[2] "second"
]
Obviously only the zeroth and second elements are useful to me. What do you recommend as the neatest way of achieving what I'm trying to do?
You can instruct the regexp to not capture the group using ?:.
my_string.split(/\s?(?:\,|and)\s?/)
# => ["first", "second"]
As an aside note
into a database using rails.
Please note this has nothing to do with Rails, that's Ruby.

Create Relationship in nodes and Using quotes and back tick in Cypher - Neo4J

I am a newbie to Neo4j, I have created two nodes with the below Cypher , how can I create a relationship between them ?
CREATE (Someone { name:'Abhilash',from :'Kerala',knows:'java' }) return someone;
CREATE (Someone { name:'Theo',worked :'WALMART',from:'kUNOOR' });return someone;
The relationship is 'Team: QualityControl'.
Second Question
Also I have seen in some create node queries that are using back tick (`) symbols in code.
e.g.
CREATE (_1:`Someone` { `name`:"Abhilash",`from`:"Kerala":,`knows`:"java" })
Whats the difference between the first create statement and the above create statement ?
Can we create properties of nodes as
{key:'Values'} or {<back tick> key <back tick>:"Values"}
where < back tick > is `
Am much confused with the different ways of using tick(`) , double Quote ("") ans single quote (') inside the query . Can any one help me to understand the right scenarios of using these characters ?
Update
thanks for the clarification . i used the below query to create the relationship , but its not returning any result or creating a relationship between my nodes . this is my statement,
MATCH (a:someone),(b:someone)
WHERE a.name = 'Abhilash' AND b.name = 'Theo'
CREATE a-[r:RELTYPE]->b
RETURN r
Backtick is only used if you have a character in a property name or reltype that isn't valid to cypher, such as spaces or hyphens. I recommend avoiding the need to use backticks.
Double quotes and single quotes are interchangeable to represent strings, similar to JavaScript. I usually go the route of using double quotes and escaping internal double quotes with backslash: {dialog:"Joe said, \"Hello World.\""}...
As an aside, you probably don't want to use "Team: Quality Control" as a relationship. That should probably be a node with relationships to each team member.

Resources