Using a map element in MATCH statement - dictionary

I have a query written out where one of the lines is as follows:
[individualNode IN listOfNodes | [(individualNode)-[:CONNECTED_WITH]->(otherNode) | {node:otherNode, similarity:individualNode['similarity']}]] AS connectionMap
listOfNodes is a List of maps
Example of one of the map in the list is
{
"similarity":0.25,
"node":{
"identity":12345,
"labels": [
"Label1",
"Label2"
],
"properties": {
yada..yada..
}
}
The issue here is that since individualNode is a map the statement (individualNode)-[:CONNECTED_WITH]->(otherNode) will fail.
So my question is how do i access the node to use in the match statement, but still retain the map so i can grab the similarity value.
Disclaimer: I know node is a special word in cypher, i only used it here so you guys know what it is i am talking about in the map. That's not how it is in my actual query.
I also change the names of things because i cannot reveal the actual information in the map.
I have tried to write it as (individualNode.node)-[:CONNECTED_WITH]->(otherNode) or (individualNode['node'])-[:CONNECTED_WITH]->(otherNode) but both throw errors too.

Do you want to use it later?
You can access maps with their keys, e.g. map.node
if you want to use that in a pattern you have to alias it with an identifier
e.g. WITH map.node as startNode MATCH (startNode)-->(...)
if you have a list of nodes like in your case you either can walk through that in a pattern comprehension again, like you already did
or you can use UNWIND to turn the list into rows.
UNWIND listOfNodesMaps as map
WITH map.node as startNode, map.similarity as similarity
MATCH (startNode)-->(...)

Related

find all edges for a result set of nodes

I have a query that returns a set of nodes, like this:
g.V().as("a","node").has("prop1", true).out().as("b","node").hasLabel("device")
.in().as("c","node").hasLabel("lbl1").has("prop1", false).select("a","b","c").limit(200)
Now I want to return all these nodes and any edge between them as my result. I tried the following but it always comes back empty:
g.V().(....)
.select("a","b","c").limit(200)
.select("node").dedup().fold().as('all')
.unfold().as('start').bothE().as('edge').otherV().as('end')
.where(within('all'))
.select('start', 'edge', 'end').dedup()
unfortunately this always comes back empty. I think my where filter is incorrect. How do I filter the result for only those where node "c" is one of those in "a"?
I want to keep this generic so I can use it to process multiple different queries that all return a set of nodes.
For this query, you should check that out vertex is in the set of the beginning vertex. So you should first fold() the start set and then check against it with within() predicate inside where
Here is query for example g = TinkerFactory.createModern().traversal()
g.V().limit(3).fold().as('all').
unfold().as('a').outE().as('b').otherV().as('c').
where(within('all')).
select('a', 'b', 'c')
See 2nd example here: https://tinkerpop.apache.org/docs/current/reference/#where-step

Using Neo4j Cypher to obtain the longest path without the first or last node

I have a forest of nodes and relationships. Similar to the following:
N1-sends->N2-sends->N3-sends->N4
N5-sends->N6-sends->N7-sends->N8
N9-sends->N10-sends->N11-sends->N12-sends->N13
I want to write a Cypher query that returns the 3 paths, without the first or last item. The nodes that are NOT at the beginning or end of the paths already have a property("middle", "true"), so that makes it easier.
A problem that I have encountered is that Cypher returns the path and every SUBSET of the path as well. For example it returns n10->n11-> and n11->n2, and n10->n11->n12, .... which is not what I want.
Instead I just want the results to be an array of 3, where inside each I have:
n2->n3
n6->n7
n10->n11->n12
and thats it.
The queries that I have came up with are: (first one has syntax errors):
START n=node(*) MATCH p=()-[*]->i-[*]->() WHERE has(i.middle)
WITH COLLECT(p) AS pa, MAX(length(p)) AS maxLength, NODES(p) AS pn
FILTER(path IN pa WHERE length(path)=maxLength) AS longestPaths
RETURN DISTINCT FILTER(x IN longestPaths WHERE exists(x.middle))
and
START n=node(*) MATCH p=()-[*]->i-[*]->()
WHERE has(i.middle)
RETURN DISTINCT filter(x IN NODES(p) WHERE exists(x.middle)) as O
The second one returns the paths without the first and last node, but it returns duplicated nodes, because it returns subsets of path as well..
Thank you.
This might do what you want:
MATCH (n)-[:sends*]->(m)
WHERE NOT ( ()-[:sends]->(n) OR (m)-[:sends]->() )
RETURN NODES(p)[1..-1] AS middleNodes;
The WHERE clause eliminates sub-paths (i.e., paths that are part of a longer path). The NODES(p)[1..-1] syntax returns the second through next-to-last nodes in each path.

DSE cassandra and spark map collections type: how to perform get operation

For example I have the following table named "example":
name | age | address
'abc' | 12 | {'street':'1', 'city':'kl', 'country':'malaysia'}
'cab' | 15 | {'street':'5', 'city':'jakarta', 'country':'indonesia'}
In Spark I can do this:
scala> val test = sc.cassandraTable ("test","example")
and this:
scala> test.first.getString
and this:
scala> test.first.getMapString, String
which gives me all the fields of the address in the form of a map
Question 1: But how do I use the "get" to access "city" information?
Question 2: Is there a way to falatten the entire table?
Question 3: how do I go about counting number of rows where "city" = "kl"?
Thanks
Question 3 : How do we count the number of rows where city == something
I'll answer 3 first because this may provide you an easier way to work with the data. Something like
sc.cassandraTable[(String,Map[String,String],Int)]("test","example")
.filter( _._2.getOrElse("city","NoCity") == "kl" )
.count
First, I use the type parameter [(String,Map[String,String],Int)] on my cassandraTable call to transform the rows into tuples. This gives me easy access to the Map without any casting. (The order is just how it appears when I made the table in my test environment you may have to change the ordering)
Second I say I would like to filter based on the _._2 which is shorthand for the second element of the incoming tuple. getOrElse returns the value for the key "city" if the key exists and "NoCity" otherwise. The final equivalency checks what city it is.
Finally, I call count to find out the number of entries in the city.
1 How do we access the map?
So the answer to 2 is that once you have a Map, you can call get("key") or getOrElse("key") or any of the standard Scala operations to get a value out of the map.
2 How to flatten the entire table.
Depending on what you mean by "flatten" this can be a variety of things. For example if you want to return the entire table as an array to the driver (Not recommended since your RDD should be very big in production.) You can call collect
If you want to flatten the elements of your map into a tuple you can always do something like calling toSeq and you will end up with a list of (key,value) tuples. Feel free to ask another question if I haven't answered what you want with "flattening."

rewrite rules that converts tokens to integer parameters

After much wrestling with the idea of ranking records, I finally settled on numeric based scores for my documents, which I emit to have them sorted based on these scores.
Now these numbers have meaning, where the 1st 2 digits represent a specific type of document.
Therefore, to get documents of type 22 sorted based on their scores, I simply query the view with start key being 220000 and end key being 229999
This is all great and works, my problems occur when I try to use url rewrites.
I'm basically trying to reroute:
/_rewrite/rankings/{doctype}
to
/_list/rankings?startkey=xx0000&endkeyxx9999
where xx is the {doctype}
my issue is with specifying rewrite rule:
[
{ "from":"rankings/:doctype",
"to":"_list/rankings",
"query": ??? //what will this be?
]
How can I construct the start and end keys by appending 0000 and 9999 respectively?
how can I specify a numeric value? since using place holder ":doctype" will result in a string type rather than a numberic type, resulting in a failed query even if I were to modify my pretty url to input both start and end keys.
I worked around the issue by filtering the results in my list view (ignoring docs im not interested in from getRow()), my concern here, should I worry about efficiency of list function now?
feel free to comment also on my sorting strategy .. would be interested to know how others solved their sorting and slicing problems with couchdb
Solution
First, you should emit the type and the score separately in an array instead of concatenating them:
emit([doc.type, doc.score], doc);
Then you can rewrite like this
[
{
"from" : "rankings/:doctype",
"to" : "_list/rankings/rankings",
"query" : {
"startkey" : [":doctype", 0],
"endkey" : [":doctype", 9999]
},
"formats": {
"doctype" : "int"
}
}
]
I tested it on CouchDB 1.1.1 and it works.
Reference
The relevant documentation is buried in this issue on JIRA: COUCHDB-1074
As you can see, the issue was resolved on April 2011, so it should work in CouchDB 1.0.3 and above.

Programmatically getting a list of variables

Is it possible to get a list of declared variables with a VimL (aka VimScript) expression? I'd like to get the same set of values that will be presented for a command using -complete=expression. The goal is to augment that list for use in a user-defined command completion function.
You can use g: as a dictionary that holds all global variables, so:
let globals = keys(g:)
will give you all the names. The same applies to the other scopes: b:, s:, w:, etc. See :help internal-variables for the complete list.
You can get something similar using keys of g:, b:, t:, w: and v: dictionaries, but beware of the following facts:
There is no equivalent to this dictionaries if you want to complete options.
Some variables like count (but not g:count or l:count), b:changedtick and, maybe, others are not present in this dictionaries.
Some vim hacker may add key ### to dictionary g:, but it won't make expression g:### valid variable name (but adding 000 there will). Though g:["###"] will be a valid expression.

Resources