Neo4j find nodes with the same properties - graph

I have a Neo4j graph where each node is a person. Each person has two properties: Name and City. And the relationships are: friend_of and love.
I'm trying to get the nodes that have friends ONLY in their same city (A live in Paris, B in Paris, C in Madrid, D in Madrid, A-[friend_of]->B, B-[friend_of]->C a A-[friend_of]->C, D-[friend_of]->C I only need to get A and D because their friends live in their same city and only there) and order them by City first and then by Name.
I have tried the following:
MATCH (n)-[r:FRIEND_OF]-(n1) WHERE (n.City = n1.City) RETURN n,n1 ORDER BY n.City, n.Name
That gives me the nodes wanted, but some of them are wrong too (they have friends in other cities).
Thank you!

Based on the following neo4j console http://console.neo4j.org/r/5c2n8h, this query returns you only D as wanted :
MATCH (user:User)-[:FRIEND_OF]-(friend)
WITH user, collect(friend) AS friends
WHERE ALL (f IN friends WHERE f.City = user.City)
RETURN user
ORDER BY user.City, user.name

Try this:
MATCH (u:User {name:"carlos"})-[:FRIEND_OF]-(f:User)
WITH u, collect(f) as friends
WHERE ALL(f in friends WHERE f.City = u.City)
UNWIND friends as friend
RETURN friend
ORDER BY friend.City, friend.Name

Related

Custom dimensions property with multiple entries in Azure Applications Insights

my logs contain in customDimensions multiple entries.
{"MessageType":"EventLog","Properties":"{\"Action\":\"Manual Trigger\",\"City\":\"New York\"}","AppBuild":"22"}
How do I extract the entries in "Properties" and put them in separate columns?
{\"Action\":\"Manual Trigger\",\"City\":\"New York\"}
Action
City
Manual Trigger
New York
For some reason, the entries in "Properties" do not have the same order. Sometimes "City" can be first.
I could extract properties, but this is only halfway
let events = customEvents
| extend properties = tostring(customDimensions["Properties"])
or
let events = customEvents
| extend properties = tostring(customDimensions.Properties)
Splitting the result could work, except, that the entries do not have the same order for each log entry.
you could use the bag_unpack() plugin.
for efficiency, make sure you specify the output schema (in this case (Action: string, City: string))
datatable(customDimensions:dynamic)
[
dynamic({"MessageType":"EventLog","Properties":"{\"Action\":\"Manual Trigger\",\"City\":\"San Francisco\"}","AppBuild":"21"}),
dynamic({"MessageType":"EventLog","Properties":"{\"Action\":\"Manual Trigger\",\"City\":\"New York\"}","AppBuild":"22"})
]
| extend properties = parse_json(tostring(customDimensions.Properties))
| evaluate bag_unpack(properties) : (Action: string, City: string)
Action
City
Manual Trigger
San Francisco
Manual Trigger
New York

Creating a graph from Neo4j Data in R

I have a dataset which consists of Users and Repositories, which I query against Neo4j
query = "
MATCH (user:User{name:'mattt'})-->(repo)
MATCH (repo)<--(allUsers:User)
RETURN repo.name, COLLECT(DISTINCT allUsers.name) AS users;
"
q = cypher(neo4j, query)
The relation is between the repo.name and a list of users point to it.
I am having trouble figuring out how to restructure the data to plot this in a graph.
I think you want to use a Cypher query that returns an edgelist, rather than having a list of all users that given user points to. Something like this:
MATCH (u:User)-->(r:Repo)
RETURN u.name AS from, r.name AS to;
Following along from this blog post about network visualization using RNeo4j:
query = "
MATCH (u:User)-->(r:Repo)
RETURN u.name AS from, r.name AS to;
"
edges = cypher(neo4j, query)
Then define a DataFrame for the nodes:
nodes = data.frame(id=unique(c(edges$from, edges$to)))
nodes$label = nodes$id
Then to visualize using the visNetwork libary:
visNetwork(nodes, edges)

TYPO3 Extbase order by child records COUNT

I have this model:
News -> 1:n -> Visit
News -> m:n -> FrontendUserGroup
FrontendUser -> 1:n -> Visit
So Visit shows which FrontendUser accessed which News.
I need to get all news for the currently logged in FrontendUser.
All News should be ordered DESC by the "datetime" property, but first should appear the news which are not visited yet by the logged in user.
This is the SQL which gives me the correct results:
SELECT
(SELECT COUNT(*) FROM tx_xxnews_domain_model_visit v WHERE v.news = n.uid AND v.fe_user = fu.uid) AS visits,
n.*
FROM tx_xxnews_domain_model_news AS n
JOIN tx_xxnews_news_frontendusergroup_mm nfg ON n.uid = nfg.uid_local
JOIN fe_users fu ON FIND_IN_SET(nfg.uid_foreign, fu.usergroup)
WHERE fu.uid = 2271 # logged in user id
ORDER BY visits ASC, n.datetime DESC
Is there any way to get this result with Extbase?
I tried in NewsRepository this:
protected $defaultOrderings = array(
'COUNT(visits)' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING,
'datetime' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
);
but it doesn't seem to work.
Any ideas?
Thank you.
This is in fact not possible since $defaultOrderings expects properties, not SQL field names or functions.
As far as I know, the only possibility is to use$query->statement('[YOUR QUERY]');.

JOIN WITH entity.collection Doctrine 2

I've been trying a lot of different things but I can't seem to find a way to JOIN... WITH an entity's attribute as a collection.
Say I have users and contacts. Because of reasons, I want to make a query such as :
SELECT c FROM Bundle:Contact c
LEFT JOIN Bundle:User u WITH c.user = u
WHERE c IN u.contacts
I know this query doesn't seem to make any sense, but the actual query I'm working on does :)
So Doctrine does not accept that query as it expects a SELECT...FROM after the IN.
How do I make a query so that I can check that c belongs to the collection u.contacts? How does one restrain selection according to select in an entity's attribute?
Try MEMBER OF:
SELECT c FROM Bundle:Contact c
LEFT JOIN Bundle:User u WITH c.user = u
WHERE c MEMBER OF u.contacts
Ok, to be honest, I have no idea what you are trying to do. I will give you 2 examples, one will probably be what you need or at least give you an idea what to do.
First problem; your WITH and IN conditions doesn't really make much sense for me. If you want to JOIN only some Users, you should do this:
//ContactRepository
public function findMeSomething()
{
$subquery = "SELECT s1.id FROM Bundle:User s1 WHERE ... some condition" ;
return $this->createQueryBuilder("c")
->leftJoin("c.Users", "u", "WITH", "u.id IN ($subquery)"
...
This would join contact with its users; not all, users would be limited by $subquery.
Second: if you want to limit fetching contacts (primary select), then
$subquery = "SELECT s1.id FROM Bundle:Contact s1 WHERE ... some condition" ;
->where("c.id IN ($subquery)"

Cypher Order By Number of Paths

Let's say I have a graph of movies and directors, where movies are connected to each other by co-viewership. I want to find similar directors, i.e. directors whose films tend to be watched together.
START n=node:index(Name="Steven Spielberg") MATCH n-->m--l<--o RETURN o;
This gets me all of the related directors, but how do I order them by the number of paths that connect them? Bonus points if I can also take weight of the tie between films into consideration.
count(*) is the number of paths that start with n and end with o
START n=node:index(Name="Steven Spielberg")
MATCH n-->m--l<--o
RETURN o,count(*)
order by count(*) desc;
with weights on the relationships
START n=node:index(Name="Steven Spielberg")
MATCH path=n-->m--l<--o
RETURN o,sum(reduce(sum=0,r in rels(path) : sum+r.weight)) as weight
ORDER BY weight desc;
START n=node:index(Name="Steven Spielberg")
MATCH path=n-->m--l<--o
RETURN o
ORDER BY length(path);

Resources