I stumbled uppon the same problem like in neo4j - Relationship between three nodes. I am new in Neo4J and wanted to model a relational database as a graph.
I have three types of data, A, B and C. An instance of B, B1, can belong to an instance of C, C1, and an instance of A, A1 can belong to B1 and C1, but if and only if B1 belongs to C1. The problem here is that, i can also have A1 belonging to B2 which belongs to C1 and A1 also belonging to B1 which belongs to C2. These would be three legit, separate combinations. So, in my DB, i would have a join table where in a record i would keep the combination of the three ids, expressing the relationships formed by the instances.
Now, from what i can figure, hyperedges is something like what i am searching(http://neo4j.com/docs/stable/cypher-cookbook-hyperedges.html). I was thinking, for starters, to add relationships like these:
A-[:PART_OF]->TRIPLE
B-[:PART_OF]->TRIPLE
C-[:PART_OF]->TRIPLE
1st problem/question: if a type B instance was to be deleted then the triple node would remain. I am guessing i would have to handle this in some way when deleting things?
2nd problem/question: My main question is, would it be more efficient if i added some more relationships? For example A-[:BELONGS_TO]->C. So, if i wanted all type C instances that A1 belongs to, i could have the results back with one hop. The relationship traversals would be less in number than the "triple" type nodes that would have to be visited. I think basically i am asking how Neo4j is looking for patterns internally(Where does it start, does it re-examine nodes etc). Because i am guessing(maybe wrongfully) if i want the Cs that A1 belongs to, i would write something like:
match A1-[:PART_OF]->triple<-[:PART_OF]-C
return C
How would that query work? First retrieve all triples A1 is part of, then those all C types are part of and finally return the matches?
Any hints?
Thanks in advance.
If I understand you correctly, you really want to represent a transitive relationship, as in:
(:A)-[:BELONGS_TO]->(:B)-[:BELONGS_TO]->(:C)
If so, there is no need to use "triplets", as neo4j can easily represent and handle transitive relationships.
Suppose your test data (as stated in your question) is created this way:
CREATE
(a1:A {name:"a1"}),
(b1:B {name:"b1"}), (b2:B {name:"b2"}),
(c1:C {name:"c1"}), (c2:C {name:"c2"}),
(a1)-[:BELONGS_TO]->(b1),
(b1)-[:BELONGS_TO]->(c1),
(b1)-[:BELONGS_TO]->(c2),
(a1)-[:BELONGS_TO]->(b2),
(b2)-[:BELONGS_TO]->(c1)
With that data, you can use the following query to get the C nodes that a specific A node indirectly belongs to. This query also returns the path that was used, since there can be multiple paths between any specific A and C pair. Here is a console that shows this working.
MATCH p=(:A { name:"a1" })-[:BELONGS_TO*2..2]->(c:C)
RETURN p, c;
If you just wanted distinct C nodes in the result, this would do that:
MATCH (:A { name:"a1" })-[:BELONGS_TO*2..2]->(c:C)
RETURN DISTINCT c;
Related
I have an Student object that is enrolled (propertyObject) with a Course.
I need to restrict that the same student cannot be enrolled in the same course more than 1 time.
How to write that in OWL/Protégé?
Please!
You don't need the restriction, it is implicit in the language.
You have individual A, a student, and individual B, a course.
If you try to specify that A is enrolled in B twice, you have two axioms:
A isEnrolledIn B
A isEnrolledIn B
OWL ontologies are /sets/ of axioms, therefore the two axioms disappear and only one is left.
I have a model called lists, which has a column called item_ids. item_ids is a JSON column (MySQL) and the column contains array of UUIDs, each referring to one item.
Now when someone creates a new list, I need to search whether there is an existing list with same set of UUIDs, and I want to do this search using query itself for faster response. Also use ActiveRecord querying as much as possible.
How do i achieve this?
item_ids = ["11E85378-CFE8-39F8-89DC-7086913CFD4B", "11E85354-304C-0664-9E81-0A281BE2CA42"]
v = List.new(item_ids: item_ids)
v.save!
Now, how do I check whether a list exists which has item ids exactly matches with that mentioned in query ? Following wont work.
list_count = List.where(item_ids: item_ids).count
Edit 1
List.where("JSON_CONTAINS(item_ids, ?) ", item_ids.to_json).count
This statement works, but it counts even if only one of the item matches. Looking for exact number of items.
Edit 2
List.where("JSON_CONTAINS( item_ids, ?) and JSON_LENGTH(item_ids) = ?", item_ids.to_json, item_ids.size).count
Looks like this is working
You can implement a has many relation between lists and items and then access like this.
List.includes(:item).where('items.id in (?)',item_ids)
To implement has_many relation:
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
I want to merge two records created with the same constructor.
Record A gets initialized with values for the fields a,b,c while record B gets initialized with a value only forfoo.
The constructor has default values for all fields, so both records have a,b,c,foo as fields.
Now I want to merge Record B "on top of" A, such as the new record, will contain a,b,c from A and foo from B.
What actually happens, is that B completely overrides the values in A (admittedly, this sounds logical).
Is there a known / easy way to merge the records, excluding default values? I am thinking something along writing a function that recognizes the constructor, finds the default values from a config file, and has some logic to exclude default values, but that sounds error prone (how do I diffrentiate between a default value, and a value that is legitimate, but is exactly like the default?).
Also, I am working in an existing codebase and would like to make changes as small as possible.
i think you want mergeWith docs
it might even make sense to hang a method off of either / both type A and type B to expose your custom merge logic. this would allow you to more easily identify default values (since presumably they'll be in scope) as well as provide convenient access.
usage would look something like:
a instanceof A; //=> true
b instanceof B; //=> true
a.mergeB(b); //=> a w/ some or all of b's data
b.mergeA(a); //=> b w/ some or all of a's data
I have a nested repeated structure, the repeated structure is of variable length. For example, it could be a person object with a repeated structure that holds cities the person has lived in. I'd like to find the last item in that list say to find current city person lives in. Is there an easy way to do this, I tried looking around jsonpath functions but I'm not sure how to use it with "within". Any help please?
1) You can use LAST and WITHIN
SELECT
FIRST(cell.value) within record ,
LAST(cell.value) within record
FROM [publicdata:samples.trigrams]
where ngram = "! ! That"
2) or if you want something more advanced you can use POSITION
POSITION(field) - Returns the one-based, sequential position of field within a set of repeated fields.
You can check the samples from trigrams (click on Details to see the unflatten schema)
https://bigquery.cloud.google.com/table/publicdata:samples.trigrams?pli=1
And when you run POSITION, you get the ordering of that field.
SELECT
ngram,
cell.value,
position(cell.volume_count) as pos,
FROM [publicdata:samples.trigrams]
where ngram = "! ! That"
Now that you have the position, you can query for last one.
We want to set up a directory of all the organizations working with us. They are incredibly diverse (government, embassy, private companies, and organizations depending on them ). So, I've resolved to create 2 tables. Table 1 will treat all the organizations equally, i.e. it'll collect all the basic information (name, address, phone number, etc.). Table 2 will establish the hierarchy among all the organizations. For instance, Program for illiterate adults depends on the National Institute for Social Security which depends on the Labor Ministry.
In the Hierarchy table, each column represents a level. So, for the example above, (i)Labor Ministry - Level1(column1), (ii)National Institute for Social Security - Level2(column2), (iii)Program for illiterate adults - Level3(column3).
To attach an organization to an hierarchy, the user needs to go level by level(i.e. column by column). So, there will be at least 3 situations:
If an adequate hierarchy exists for an organization(for instance, level1: US Embassy), that organization can be added (For instance, level2: USAID).--> US Embassy/USAID, and so on.
How about if one or more levels are missing? - then they need to be added
How about if the hierarchy need to be modified? -- not every thing need to be modified.
I do not have any choice but working by level (i.e. column by column). I does not make sense to have all the levels in one form as the user need to navigate hierarchies to find the right one to attach an organization.
Let's say, I have those queries in my repository (just that you get the idea).
Query1
var orgHierarchy = (from orgH in db.Hierarchy
select orgH.Level1).FirstOrDefault;
Query2
var orgHierarchy = (from orgH in db.Hierarchy
select orgH.Level2).FirstOrDefault;
Query3, Query4, etc.
The above queries are the same except for the property queried (level1, level2, level3, etc.)
Question: Is there a general way of writing the above queries in one? So that the user can track an hierarchy level by level to attach an organization.
In other words, not knowing in advance which column to query, I still need to be able to do so depending on some conditions. For instance, an organization X depends on Y. Knowing that Y is somewhere on the 3rd level, I'll go to the 4th level, linking X to Y.
I need to select (not manually) a column with only one query that takes parameters.
=======================
EDIT
As I just said to #Mark Byers, all I want is just to be able to query a column not knowing in advance which one. Check this out:
How about this
Public Hierarchy GetHierarchy(string name)
{
var myHierarchy = from hierarc in db.Hierarchy
where (hierarc.Level1 == name)
select hierarc;
retuen myHierarchy;
}
Above, the query depends on name which is a variable. It mighbe Planning Ministry, Embassy, Local Phone, etc.
Can I write the same query, but this time instead of looking to much a value in the DB, I impose my query to select a particular column.
var myVar = from orgH in db.Hierarchy
where (orgH.Level1 == "Government")
select orgH.where(level == myVariable);
return myVar;
I don't pretend that select orgH.where(level == myVariable) is even close to be valid. But that is what I want: to be able to select a column depending on a variable (i.e. the value is not known in advance like with name).
Thanks for helping
How about using DynamicQueryable?
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Your database is not normalized so you should start by changing the heirarchy table to, for example:
OrganizationId Parent
1 NULL
2 1
3 1
4 3
To query this you might need to use recursive queries. This is difficult (but not impossible) using LINQ, so you might instead prefer to create a parameterized stored procedure using a recursive CTE and put the query there.