I have a graph were user can have a post and also can have a friend that have a post , the friend can be followed or not .
how can i query all the posts by the user and the friends that he is following ?
I tried this :
" MATCH (u1:User)-[:POSTED]->(p1:Post)"
+ " WHERE u1.username =~ '"+user+"'"
+ " OPTIONAL MATCH (u3:User)-[:FOLLOWING]->(u2:User)-[:POSTED]->(p2:Post),"
+ " (u3:User)-[:FRIEND_OF]->(u2:User)"
+ " WHERE u3.username =~ '"+user+"' return u1.username, u1.name,"
+ "p1 ,u2.username, u2.name , p2";
but this query returns duplicates, lets say we have our user and a friend .
the frien have one post and the user have two , the query returns the friend post twice its like for every MATCH the query returns also the result of OPTIONAL MATCH .
to further exaplain:
(u:User)-[:POSTED]->(p:Post)
(u:User)-[:FRIEND_OF]->(u2:User)
(u:User)-[:FOLLOWING]->(u2:User)-[:POSTED]->(p2:Post)
these are the relationships that exist what i want is all Posts (:Post) that meet those relationships without duplicates and preferably with single query .
First of all, your query is much more complex than it needs to be. This simpler query should be equivalent. I assume that {user} is supplied as a parameter.
MATCH (u1:User {username: {user}})-[:POSTED]->(p1:Post)
OPTIONAL MATCH
(u1)-[:FOLLOWING]->(u2:User)-[:POSTED]->(p2:Post),
(u1)-[:FRIEND_OF]->(u2)
RETURN u1.username, u1.name, p1, u2.username, u2.name, p2;
The reason you get multiple rows with the same p2 values is because your RETURN clause is returning values related to u1 and u2 together. If there are N u1/p1 results and M u2/p2 results, then you'd get N*M result rows.
To get a result with N rows (with one row per u1/p2 result), you can use something like this query:
MATCH (u1:User {username: {user}})-[:POSTED]->(p1:Post)
OPTIONAL MATCH
(u1)-[:FOLLOWING]->(u2:User)-[:POSTED]->(p2:Post),
(u1)-[:FRIEND_OF]->(u2)
RETURN
u1.username, u1.name, p1,
COLLECT({username: u2.username, name: u2.name, p2: p2}) AS friends;
Each result row will have a friends collection with the data for each relevant friend.
Related
I have to search certain nodes like eq.page whether or not they have relation or not with some other node..like tags.
If they are connected to tag nodes then search for the search string in page name and the tag names
Else search for the search string in page name only
MATCH ...//nodes of certain type
WHERE
if r is null'
...//Match query without relation for searching
else
...//Match query without relation for searching
Return ...
MATCH (n:page)<-[r:pagetag]-(tag)
if r is null
then n.title CONTAINS 'java'or tag.name IN ["java"]
return distinct n.name
else n.title CONTAINS 'java'return distinct n.name
END
This query is giving error. May be syntax problem. But I want to search for like this only for the pages.
Finally acheieved what I wanted. Thanks all. OPTIONAL Match worked great for me.
MATCH (s:page)
WITH s
OPTIONAL MATCH (s)<-[r:pagetag]-(tag)
WITH s,r,tag
Where s.pagename contains 'juniors'or tag.name contains 'math'
return distinct s.pagename
Isn't that just basic conditionals?
MATCH (n:page)<-[r:pagetag]-(tag)
WITH n,r,tag
WHERE r IS NULL AND (n.title CONTAINS 'java' or tag.name IN ["java"])
OR NOT r is NULL AND (n.title CONTAINS 'java')
return distinct n.name
I don't think you can use if else in Neo4j you have to use case, or foreach to simulate if .
I have a search functionality that is implemented on my current project, I am using HQL for the repo method - Everything is okay except searching for special characters for some reason HQL is not escaping it.
#Query("SELECT f FROM Item f WHERE f.id=:id AND f.itemNm LIKE %:itemNm %")
Item findByItemNm(#Param("itemNm ") String itemNm, #Param("id") Long id);
The String search I am sending is
abc_xyz(YYYYMM[t-2]-YYYYMM[t-1])_[xyz]HU.xlsx
Debugging Steps
Before sending to the Repo - I did replace all the special characters with the following -newsearchString is the one thatt is being passed to the repo
String newsearchString = searchString.replaceAll("(?=[]\\[+&|!(){}^\"~*?:\\\\_]) ", "/");
I have also tried it without replacing the special characters- It is not being returned
How do you escape characters in HQL?
Here is the solution for your problem...It should work for your need.
1) Find and replace all your escape characte, and replaced by "\\"
Example: [hi]_mysearch should be replaced like \\[hi\\]_mysearch
2) Change your repo query like below
#Query("SELECT f FROM Item f WHERE f.id=:id AND f.itemNm LIKE %:itemNm % escape '\\'")
Item findByItemNm(#Param("itemNm ") String itemNm, #Param("id") Long id);
HQL does not have regular expressions out of the box. You'd have to modify the Dialect for your specific database to add that functionality. (Oracle example)
If you're just trying use like with the % wildcard, then you can do the following:
String itemNm = "abc_xyz(YYYYMM[t-2]-YYYYMM[t-1])_[xyz]HU.xlsx";
Query q = session.createQuery("from Item where itemNm like :itemNm ";
q.setString("itemNm","%"+itemNm+"%");
I have a graph that displays a finance relation between companies - the relation of owes , which companies owe money to companies . I seek a unique relations - circles , which are latter closed .So if I owe You money and we find that somehow you owe me money me close the debt . The companies are identified by tax number. For this I use this Cypher query :
start n=node(*)
match p=n-[r:OWES*1..200]->n
where HAS(n.taxnumber)
return extract(s in relationships(p) : s.amount),
extract(t in nodes(p) : ID(t)),
length(p) ;
But I also get results like
Company1-Company2-company1-Company-3
I display this results back in my java application . Should I maybe hide this results after I parse them in java code - results where one company is shown twice .
This is fine when it comes to logic but I need results where a company is shown only once , I do not want results where I get the same company multiple times . How to modify my Cypher query for that ? What I want is that the company in the results can be only at the beginning and at the end of the result and not somehow circled in the middle .
You can try to check the path-nodes to not contain your start node.
start n=node(*)
match p=n-[:OWES*1..200]->(m), (m)-[r:OWES]->n
where HAS(n.taxnumber)
AND NOT(n IN tail(nodes(p)))
return extract(s in relationships(p) : s.amount) + r.amount,
extract(t in nodes(p) : ID(t)) + ID(n),
length(p) + 1;
Unfortunately there is no subscript in 1.8.2 and only tail(coll) no simple way to exclude the last element from a check. That's why I have to break up p and fix your aggregations at the end.
I am using Google App Engine for a project and I need to do some queries on the database. I use the JDOQL to ask the database. In my case I want to obtain the university that contains the substring "array". I think my query has a mistake because it returns the name of universities in the alphabetical order and not the ones containing the substring.
Query query = pm.newQuery("SELECT FROM " + University.class.getName() + " WHERE name.contains("+array+") ORDER BY name RANGE 0, 5");
Could someone tell me what's wrong in my query?
Thank you for your help!
EDIT
I have a list of universities store and I have a suggestbox where we can request a university by his name. And I want to autocomplete the requested name.
App engine does not support full-text searches, you should star issue 217. However, A partial workaround is possible. And in your case I think it is a good fit.
First thing, adjust your model such that there is a lower (or upper case) version of the name as well -- I will assume it is called lname. Unless you want your queries to be case-sensitive.
Then you query like this:
Query query = pm.newQuery(University.class);
query.setFilter("lname >= startNameParam");
query.setFilter("lname < stopNameParam");
query.setOrdering("lname asc");
query.declareParameters("String startNameParam");
query.declareParameters("String stopNameParam");
query.setRange(0, 5);
List<University> results = (List<University>) query.execute(search_value, search_value + "z");
The correct way to do this is like this -
Query query = pm.newQuery(University.class,":p.contains(name)");
query.setOrdering("name asc");
query.setRange(0, 5);
List univs = q.execute(Arrays.asList(array));
(note- In this case the :p is an implicit param name you can replace with any name)
Hello guys I am having some problems with exact matches while doing a NamedQuery.
I am currently using something like this:
#NamedQuery(name = MyClass.GET_ENTRY_BY_NAME, query = "select e from Entry e where e.name =:"+ Entry.NAME )
...
Query query = em.createNamedQuery(MyClass.GET_ENTRY_BY_NAME);
query.setParameter(Entry.NAME, myEntry.getName());
It works for most cases, however I noticed that in case the user pass the file name with an space at the end, the namedQuery ignores that character. For example:
Query query = em.createNamedQuery(MyClass.GET_ENTRY_BY_NAME);
query.setParameter(Entry.NAME, myEntry.getName()+ " ");
Will return the same result as the query before. Bypassing my 'valid entry' validation. In other words I'd like the query to return no entry at all and treat the error later on.
One workaround I could think of, is to put single quotes surrounding my parameter in the namedQuery, like this:
#NamedQuery(name = MyClass.GET_ENTRY_BY_NAME, query = "select e from entry e where e.name =':"+ Entry.NAME "'")
However it will trash my code in case the String contains single quotes in it...
Any ideas guys?
I guess this happens because your database field is declared as CHAR(...), and therefore stored values are padded with whitespaces which are not taken into account by = operation.
So, you may either declare your database field as VARCHAR(...) or use a built-in trim function:
query = "select e from Entry e where trim(trailing from e.name) =:"+ Entry.NAME
I did some research in JPA and found out that it does some automatic trimming for CHARs, I am not sure if this behaves the same with Strings, but since it is happening to me... I believe so. The only way to bypass it is by setting some attribute within the session DatabaseLogin object (see http://www.eclipse.org/eclipselink/api/1.1/org/eclipse/persistence/sessions/DatabaseLogin.html#setShouldTrimStrings) .
Well I didn't want to be messing up with the session properties so I decided to make some sort of check and throwing the same exception as the NoResultException catch does in my code.
I basically took the result from the database and compared the field with the String I used:
query.setParameter(Entry.NAME, myEntry.getName());
...
if(!StringUtils.equals(result.getName(), myEntry.getName()){
do a cool throw just like NoResultException Catch
}
I also had to include the Trim function axtavt! This is just to make sure that if the database has a column with trailing spaces and it matches the parameter given by the user, it will be included as a valid answer. For example:
Database entry: Name = "Flavio " - Trimmed with Function = "Flavio".
Parameter passed: Name = "Flavio " - Trimmed by JPA automatic function = "Flavio".
If it isnt trimmed at all it will just Compare "Flavio " with "Flavio", returning NoResult when it was supposed to return that Entry.
Nasty workaround, but as long as there is no other way to stop the auto-trimming we will have to just make use of this sort of things.
Thanks for all the other answers!!