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)
Related
In the console, this returns two vertices:
g.V('615e6de7-3172-458b-bc68-876fd4f5ecb0','059b6de4-a463-4789-a987-7c2833950b5c')
==>v[615e6de7-3172-458b-bc68-876fd4f5ecb0]
==>v[059b6de4-a463-4789-a987-7c2833950b5c]
But when I run it in Gremlin, I get no results:
const idList = `"615e6de7-3172-458b-bc68-876fd4f5ecb0","059b6de4-a463-4789-a987-7c2833950b5c"`;
let traversal = await g.V(idList).toList();
I can get each id individually, but what is the syntax to fetch multiple ids in a single traversal?
The issue in your code is, you are trying to send a string with comma separated ids. Instead you have to send an array of ids.
const ids = ['3994', '3997'];
g.V(ids).properties()
I'm using the latest ArangoDB 3.1 on Windows 10.
Here I want to remove the collection document and edge document using the for loop. But I'm getting an error like document not found (vName).
vName contains the many collection names. But I dunno how to use it in for loop.
This is the AQL I am using to remove the documents from the graph:
LET op = (FOR v, e IN 1..1 ANY 'User/588751454' GRAPH 'my_graph'
COLLECT vid = v._id, eid = e._id
RETURN { vid, eid }
)
FOR doc IN op
COLLECT vName = SPLIT(doc.vid,'/')[0],
vid = SPLIT(doc.vid,'/')[1],
eName = SPLIT(doc.eid,'/')[0],
eid = SPLIT(doc.eid,'/')[1]
REMOVE { _key: vid } in vName
Return output im getting from the AQL (Web UI screenshot)
vName is a variable introduced by COLLECT. It is a string with the collection name of a vertex (extracted from vid / v._id). You then try to use it in the removal operation REMOVE { ... } IN vName.
AQL does not support dynamic collection names however, collection names must be known at query compile time:
Each REMOVE operation is restricted to a single collection, and the collection name must not be dynamic.
Source: https://docs.arangodb.com/3.2/AQL/Operations/Remove.html
So, you either have to hardcode the collection into the query, e.g. REMOVE { ... } IN User, or use the special bind parameter syntax for collections, e.g. REMOVE { ... } IN ##coll and bind parameters: {"#coll": "User", ...}.
This also means that REMOVE can only delete documents in a single collection.
It's possible to workaround the limitation somewhat by using subqueries like this:
LET x1 = (FOR doc IN User REMOVE aa IN User)
LET x2 = (FOR doc IN relations REMOVE bb IN relations)
RETURN 1
The variables x1 and x2 are syntactically required and receive an empty array as subquery result. The query also requires a RETURN statement, even if we don't expect any result.
Do not attempt to remove from the same collection twice in the same query though, as it would raise a access after data-modification error.
How to return the distinct relationship types from all paths in cypher?
Example query:
MATCH p=(a:Philosopher)-[*]->(b:SchoolType)
RETURN DISTINCT EXTRACT( r in RELATIONSHIPS(p)| type(r) ) as RelationshipTypes
This returns a collection for each path p.
I would like to return a single collection contain the distinct relationship types across all collections.
Here is a link to a graph gist to run the query-
http://gist.neo4j.org/?7851642
You might first collect all relationships on the matched path to a collection "allr", and then get the collection of distinct type(r) from the collection of all relationships,
MATCH p=(a:Philosopher)-[rel*]->(b:SchoolType)
WITH collect(rel) AS allr
RETURN Reduce(allDistR =[], rcol IN allr |
reduce(distR = allDistR, r IN rcol |
distR + CASE WHEN type(r) IN distR THEN [] ELSE type(r) END
)
)
Note, each element 'rcol' in the collection "allr" is in turn a collection of relationships on each matched path.
I have been trying to solve this problem and I can't seem to figure it out. I'm not sure if it's because of my db design and LINQ, but I'm hoping for some direction here.
My db table:
Id Name ParentId
1 Data1 null
2 Data2 null
3 Data3 null
4 Data4 1
5 Data5 1
6 Data6 2
7 Data7 2
Basically Data1 and Data2 are the top levels that I want to use for headings and their children will be related based on their ParentID.
I am trying to use a listview to present the data like the following:
Data1
-----
Data4
Data5
Data2
-----
Data6
Data7
I am trying to use a combination of LINQ and listview to accomplish this.
The following is the code for the linq query:
var query = from data in mydb.datatable
where data.ParentId == null
select data;
But this only gives the heading level... and unfortunately listview only takes in 1 datasource.
While it's possible with some databases (like SQL Server post 2005) to write recursive queries, I don't believe those get generated by LINQ. On the other hand, if the number of records is sufficiently small, you could materialize the data (to a list) and write a LINQ query that uses a recursive function to generate your list.
This is from memory, but it would look something like this:
Func<int?,IEnumerable<data>> f = null;
f = parentId => {
IEnumerable<data> result = from data in mydb.datatable
where data.ParentId = parentId
select data;
return result.ToList().SelectMany(d=>f(d.Id));
};
That should get you the hierarchy.
If your hierarchy has only two levels you can use a group join and anonymous objects:
var query = from data in mydb.datatable.Where(x => x.ParentId == null)
join child in mydb.datatable.Where(x => x.ParentId != null)
on data.Id equals child.ParentId into children
select new { data, children };
Edit: You will have to convert the data to a collection that can be bound to a ListView. One hack would be to have a list that is only one level deep with spacing in front of the subitems:
var listViewItems = (from item in query.AsEnumerable()
let dataName = item.data.Name
let childNames = item.children.Select(c => " " + c.Name)
from name in dataName.Concat(childNames)
select new ListViewItem(name)).ToArray();
You could also try to find a control that fits better, like a TreeView. You might want to ask a separate question about this issue.
I just wrote up a blog post describing a solution to build a graph from a self-referencing table with a single LINQ query to the database which might be of use. See http://www.thinqlinq.com/Post.aspx/Title/Hierarchical-Trees-from-Flat-Tables-using-LINQ.
I have a table called Quiz that have these fields
id As Int
created As DateTime
header As Sring
body As String
fk_parent As int
url As String
All the items without parent key would be the question, and ones that have the parent key would be the answer. I am having the problem to get all the latest active questions (based both on questions created time and and answer created time).
I am struggling to write a Linq query that can do the above task.
Here's a start:
IQueryable<int> keys =
from x in dc.Quiz
let masterID = ParentId.HasValue ? ParentId.Value : Id
group x by masterID into g
order g by g.Max(x => x.created) descending
select g.Key
List<Quiz> = dc.Quiz.Where(x => keys.Take(20).Contains(x.Id)).ToList();
This assumes answers aren't parents of answers... If they can - you have an arbitrary depth tree walk on your hands, which is a wrong shaped nail for Linq and for SQL.
You could try joining the table on itself in LINQ and creating a new object that holds the Questions and answers:
var QandA = from q in tbl
join a in tbl on q.id equals a.fk_parent
select new {
QHeader = q.header,
QBody = q.body,
QUrl = q.url,
AHeader = a.header,
ABody = a.body,
AUrl = a.url
};
I think this is how your table is setup, but I might have the join wrong.