Storing object as property in Neo4j - neo4j

I need to store an array of User objects inside a Tile node. Each User object contains three primitive properties; Id(a single alpha-character string) , fName and lName. This list of objects is a property of the Tile node with several other primitive properties. The entire Tile node needs to be serialized to Json, including the nested User objects.
I understand that Neo can't store complex objects as properties. I created the User as a separate node with id, fName and lName as properties, and I can get these returned via Cypher. I can also get Json output results for the parent Tile node. (In this case, Users is just a string of comma-separated alphas). But how do I get the User node output nested inside the parent node?
I have created a list of User objects (userList) by relating user objects with the string of user ids in the Tile Node via a Cypher Query. I just need to get from two separate json outputs to a single nested output.
I hope this is enough detail. I'm using Neo4j 2.1.6 and Neo4jClient. I'm also using .Net 4.0.

You could do something like this with cypher and have the cypher return a composite object.
MATCH (t:Tile)-[:CONTAINS_USER]-(u:User)
WHERE t.name =~ 'Tile.*'
WITH {name: t.name, users: collect(u) } AS tile
RETURN collect(tile) AS tiles

You shouldn't store another object as a nested property. As you correctly state, neo4j doesn't support that but even if it did, you shouldn't do it, because you should link the two with a relationship. That's the key strength of a graph database like neo4j, so you should play to that strength and use the relationships.
The server has a default JSON format that tends to output nodes as their own JSON objects. That means that practically speaking, since you're going to model this as two separate nodes with a relationship, you can't get the server by default to nest the JSON for one object underneath of the other. It won't nest the JSON that way because that's not how the data will be stored.
In this case, I'd use the REST services to fetch the JSON for each object individually, and then do the nesting yourself in your code -- your code is the only place where you'll know which property it should be nested under, and how that should be done.

In addition to these answers, note that if you don't need to involve the subfield properties in any of your queries (e.g. search for Tiles where a User.name is "X"), you can simply serialise the objects fields to a string before insertion (e.g. with JSON.stringify), and unserialise them when reading from the DB.
This is especially useful when you want to "attach" structured data to a node, but that you don't much care about this data with regards to the relations in your DB (e.g. User preferences).

Related

Neo4j OGM Filter query against array

I'm trying to build a small property searching system. I'm using spring boot with a neo4j database and I'm trying to query from the neo4j database using filters becasue i need the querying to be dynamic too. In my use case properties has features such as electricity, tap water, tilled roof, etc. Property & Feature are nodes, Feature node has an attribtue named 'key', a Property node is linked to many Feature nodes by rich relationships typed HAS_FEATURE, what i want to do is query properties for a given array of feature keys using Filters. Follwing is code,
featureKeys is a java List here,
filter = new Filter("key", ComparisonOperator.IN, featureKeys);
filter.setRelationshipType("HAS_FEATURE");
filter.setNestedPropertyName("hasFeatures");
filter.setNestedPropertyType(Feature.class);
filters.add(filter);
SESSION.loadAll(Property.class, filters, new Pagination(pageNumber, pageSize));
The problem is i want only the properties that related to all the given features keys to be returned, but even the properties that is related to one element of the given feature key list is also returned. What do i need to do to query only the properties that are linked to all the given list elements, i can change the rich relationship to a normal relationship if needed.

store a hash-map continer type of data on edge of neo4j

I want to store lots of data into buckets or different hash-maps between two nodes on their edges. Basically there is lot of data getting generated related to the two nodes and i want to keep the data over their edge in a hash. Since the context matters, the edge should have different buckets/hasmaps so that i can write data into and return data from the data written over the edges. How to do this in neo4j, any reference articles please.
Consider that properties are already an hash map key/value. Regarding the context you can have multiple edges between two nodes one for each context. If the contexts are limited and pre-defined you can use a specific name to the relationship that identify the context, otherwise you can add a 'context' property that allow you to identify the context.
How much data do you plan to store? How many keys in the hash map?

Optimizing Parse to query for new objects

I am using Parse as the backend for an app I'm working on. I was wondering if there is an optimal algorithm to query for only 'unseen' new objects.
What I am planning on doing is something like adding a user to the viewed object's relation and later querying all objects to check for the absence of the user. This seems to be O(n* all users who have seen an 'n') complexity which is a bit too much.
Another way to do this is to add the object to a user's key 'seen' and to then query for all objects the user has not seen.
Maybe a much more efficient way could be (assuming I view these objects chronologically) is to mark the first and last objects I see, and only show ones before or after those points using the createdAt key. Then I guess to show new objects outward from those points to not have to divide into multiple queries.
Ideally I'd like to shuffle through the objects, but I also would like to keep this algorithm as efficient as possible.
Create a Class called View. Each View consists of a unique identifier from a viewable Object (CANNOT BE THE OBJECTID) and a pointer to the User that viewed the object.
Your query should be:
//(Simple equalTo query)
Query1 = All View Objects where User pointer = User
//(whereKey:that-unique-id-column doesNotMatchKey:that-unique-id-column inQuery:Query1)
Query2 = All viewable Objects where not included in pointers in Query1

Is it possible to query the graph in neo4j with just a part of the value of a relation's property?

I am trying to move the info of data flows to a DB. The data flows are something like this:
E_App1 sends data to I_App1. I_App1 then sends this data to I_App3. I_App3 then sends this data to I_App5.
E_App2 sends data to I_App2. I_App2 then sends this data to I_App3. I_App3 then sends this data to I_App5.
E_App3 sends data to I_App2. I_App2 then sends this data to I_App4. I_App4 then sends this data to I_App5. I_App5 then sends this data to I_App6.
E_App4 sends data to I_App3. I_App3 then sends this data to I_App5. I_App5 then sends this data to I_App6.
E_App5 sends data to I_App2. I_App2 then sends this data to I_App4. I_App4 then sends this data to I_App5.
I am thinking of having a property named "OF" of the "sends data" relationship that will contain names of the data that is being sent so I can trace the flow of a particular application. Something on the lines of the below diagram. Is it possible to query the OF values, like "show all relations whose OF value contains E_App4 only"?
This is the first time I am trying Graph DB and I am thinking of using it as the relationships are complex. I am not looking for high performance here. Is there some other approach I should follow to be able to achieve the result of tracing the flow of a particular application?
Link to the diagram:http://s27.postimg.org/5qieemks3/Graph_Data_Modeling.jpg
You diagram was a little complicated, but all you are asking is to find those relationships which are of the type OF and has the node type E_App4 as the end node. There is no restricion on the start node.
So this query should work:
match (startNode) -[of:OF]->(endNode:E_App4) return startNode, of, endNode;
This ofcourse assumes the following:
the relationship will be directed from start node to end node. Hence any relationship from E_App4 as start node will not be counted. If you wish to count those also, remove the -> and replace it with -.
The start node can be anything.
ONLY the relationship of type OF is considered. Mind it, the name is case sensitive. The relationship must be labeled with OF.
End nodes must be labeled as E_App4.
Edit
Reading your question again show all relations whose OF value contains E_App4 only I guess I misunderstood you. You are asking can you check the value of the relationship. Yes you can. Here is the query:
match (startNode) -[of:OF]->(endNode) where has(of.property) and of.property = "E_App4" return of;
This assumes:
The properties defined in relationships have the key property
This will only check the relationships who has the key property. If your relationship does not have this key, those relationships will not be counted.
Thanks Rash, that helped me. I got stuck in defining the filter but some search helped me in finding out how to use *. This is for others who may get stuck as I got:
The graph is somehow like this with a lot of nodes and confusing relations with Data property only carrying the identifying information.
z-[send]->b
y-[send]->b
w-[send]->d
x-[send]->c
q-[send]->c
b-[send]->c-[send]->e
also c-[send]->d
The Data property of every relation will have the source(s) it is carrying. So relations that are way far will have many sources defined in the "send" relation's "Data" property in the manner Data:"ABC,XYZ,QWR,SDF,TYOP,Zxcvb".
//to know which all send relations have ABC part of Data property
MATCH ()-[r:send]->() WHERE r.Data =~ ".*ABC.*" RETURN r
//to know which all send relations have TYOP part of Data property
MATCH ()-[r:send]->() WHERE r.Data =~ ".*TYOP.*" RETURN r
I hope this will help someone who is still getting a hand on all this.

neo4j registering object into field

Is it possible to store an object in a field with Cypher so that the node will return some fields as
field.prop.array[0].prop1
field.prop.array[0].prop2
field.prop.array[1].prop1
field.prop2.prop3.prop4
and if so: what's the query to do it? (I've been able to store only 1 level deep objects)
In Neo4j property values can be primitives, Strings or arrays of them, see http://docs.neo4j.org/chunked/stable/graphdb-neo4j-properties.html.
To build up more nested structures you should make them explicit in the graph. A nested property might become a node that connected to the originating node.

Resources