Cypher conditions on all nodes in collection behaving incorrectly? - collections

I have this database:
CREATE (A:A {name:"A"})-[:R]->(B:B {name:"B"})-[:R]->(C:B {name:"C"})-[:R]->(D:A {name:"D"})-[:R]->(E:A {name:"E"})
This query
MATCH p = (:A)-[*]->(:B) WITH NODES(p)[1..] AS p_nodes RETURN p_nodes
returns edge (B)-->(C). And B and C have both label B. Why then does this query
MATCH p = (:A)-[*]->(:B) WITH NODES(p)[1..] AS p_nodes
WHERE ALL(x IN p_nodes[0..] WHERE LABELS(x) = "B") RETURN p_nodes
return nothing (no rows)? The only thing it does is make sure that p_nodes contains B labeled nodes only. And as the first query showed it does.

The labels(x) function will return a collection of strings, not a string. This is because nodes can have multiple labels.
So instead of comparing labels(x) = "B" use the IN operator "B" in labels(x):
MATCH p =(:A)-[*]->(:B)
WITH NODES(p)[1..] AS p_nodes
WHERE ALL (x IN p_nodes[0..]
WHERE "B" IN LABELS(x))
RETURN p_nodes

Related

Tracing a recursive function for longest common substring

I am getting confused tracing the following recursive approach to find the longest common substring. The last two lines are where my confusion is. Specifically how is the count variable getting the answer when characters of both string matches? In the last line which "count" does this refer to i.e count in the function definition or the updated count from function call? Are there any resources for better understanding of recursions?
int recursive_substr(string a, string b, int m, int n,int count){
if (m == -1 || n == -1) return count;
if (a[m] == b[n]) {
count = recursive_substr(a,b,m-1,n-1,++count);
}
return max(count,max(recursive_substr(a,b,m,n-1,0),recursive_substr(a,b,m-1,n,0)));
}
The first thing to understand is what values to use for the parameters the very first time you call the function.
Consider the two following strings:
std::string a = "helloabc";
std::string b = "hello!abc";
To figure out the length of the longest common substring, you can call the function this way:
int length = recursive_substr(a, b, a.length()-1, b.length()-1, 0);
So, m begins as the index of the last character in a, and n begins as the index of the last character in b. count begins as 0.
During execution, m represents the index of the current character in a, n represents the index of the current character in b, and count represents the length of the current common substring.
Now imagine we're in the middle of the execution, with m=4 and n=5 and count=3.
We're there:
a= "helloabc"
^m
b="hello!abc" count=3
^n
We just saw the common substring "abc", which has length 3, and that is why count=3. Now, we notice that a[m] == 'o' != '!' == b[n]. So, we know that we can't extend the common substring "abc" into a longer common substring. We make a note that we have found a common substring of length 3, and we start looking for another common substring between "hello" and "hello!". Since 'o' and '!' are different, we know that we should exclude at least one of the two. But we don't know which one. So, we make two recursive calls:
count1 = recursive_substr(a,b,m,n-1,0); // length of longest common substring between "hello" and "hello"
count2 = recursive_substr(a,b,m-1,n,0); // length of longest common substring between "hell" and "hello!"
Then, we return the maximum of the three lengths we've collected:
the length count==3 of the previous common substring "abc" we had found;
the length count1==5 of the longest common substring between "hello" and "hello";
the length count2==4 of the longest common substring between "hell" and "hello!".

function which finds a common number in multiple lists

how would this function be completed to return the common integers between two lists?
how would i complete the get_common_elements(list1, list2) function?. The function should select all the common integers from both parameters and displays them in the result.
ie numbers 1 = 3,6,8,9,12,35
numbers 2 = 6,7,13,34, 35
result = 6,35
you can assume that each number only occurs in each list once
def common_member(a, b):
a_set = set(a)
b_set = set(b)
if (a_set & b_set):
print(a_set & b_set)
else:
print("No common elements")

R - filter data from MongoDB collection

I want to use R to load a collection from mongoDB to R, with filter to increase the speed. The filter can be Or condition or IN a R data.
MongoDB collection
Name Type
A M
B P
C M
D P
E O
RFilter
Criteria
M
P
RData <- MongoCollection$find('{"Type" in RFilter$Criteria}',
fields = '{
"Name" : true,
"Type" : true
}')
I expect the output:
RData
Name Type
A M
B P
C M
D P
If you need to check-in database to check if name or type is P or M try $or in criteria as below:
{$or:[{Name:{$in:["P","M"]}},{Type:{$in:["P","M"]}}]}
The above $or condition will check in DB if the name is "P" or "M" it'll return document else it'll check in type if it values is "P" or "M" else won't return document if both are not matched.

Iterate over a list in a Match query

I have a relation that has a list of ids s_ids as a property of the relation. each id in the list correspond to another node that has a sentence corresponding to an id.I used:
MATCH (c: term)-[r: semrel]->(t: term), (b: Sentence)
Where r.source = "xyz" And b.sentence_id IN r.s_id
return r,b
to return all sentences corresponding to the relation,
the result looks like :
r b
w abc
w rty
w zxv
e nmx
e qrt
the relation r is repeated for every sentence how can I group the list of sentences corresponding to each relation to get
r b
w abc, rty, zxv
e nmx,qrt
Thanks
This should return each r and its collection of sentences:
MATCH (c: term)-[r: semrel]->(t: term), (b: Sentence)
WHERE r.source = "xyz" AND b.sentence_id IN r.s_i
RETURN r, COLLECT(b) AS sentences;
For better performance, if you create an index on :Sentence(sentence_id), like this:
CREATE INDEX ON :Sentence(sentence_id);
then this query (which adds a hint to use the index) should be faster (as the b nodes can be found using the index):
MATCH (c: term)-[r: semrel]->(t: term), (b: Sentence)
USING INDEX b:Sentence(sentence_id)
WHERE r.source = "xyz" AND b.sentence_id IN r.s_i
RETURN r, COLLECT(b) AS sentences;

Issue with multiple match statements, results no rows for valid patterns

I am trying to created a graph in Neo4j with Agents and "KNOWS"
relationship.
Match (a:AGENT {name:'a'})
Match (e:AGENT {name:'e'})
Match d1 = (a) -[r1:KNOWS]-> (e)
Match d2 = (a) -[r1:KNOWS]-> (x) -[r2:KNOWS]-> (e)
Return d2
Given:
d1 ran independently returns no rows.
d2 ran independently returns a valid result
When I run the above code though (with both the statements), the result is no rows. WHY IS d2 getting impacted by d1 resulting in no rows?
I am new to cypher and neo4j,kindly help.
Below is the DB set up at the official neo4j console:
http://console.neo4j.org/r/617mrr
d1 returns no data because there is no single hop path from a to e. Since none of you matches are optional you get no data back for the entire query.
This will cause d1 to find a match.
match (a:AGENT {name:'a'})
, (e:AGENT {name:'e'})
, d1 = (a) -[r1:KNOWS*..2]-> (e)
return d1
This is your original with a slight modification to return data.
match (a:AGENT {name:'a'}), (e:AGENT {name:'e'})
, d2 = (a) -[r1:KNOWS]-> (x) -[r2:KNOWS]-> (e)
optional match d1 = (a) -[r1:KNOWS]-> (e)
return d2
You can try like this
MATCH d2=(a:AGENT { name:'a' })-[r1:KNOWS]->(x)-[r2:KNOWS]->(e:AGENT { name:'e' })
optional match d1 = (a) -[r:KNOWS]-> (e)
RETURN d2
Is this what you needed?

Resources