neo4j query for chaining, 'knitting' pattern - neo4j

I want to write a neo4j query, that finds a 'knitting' pattern. With that I basically mean a set of four nodes with three special edges between them. And continuing these four, there can be a next set of four nodes, that are connected by three other edges, like this (in some Cypher-like syntax with vertical edges.
(n1)-[:e1]-(n2)-[:e2]-(n3)-[:e3]-(n4)
| | | |
[:ew] [:ex] [:ey] [:ez]
| | | |
(n5)-[:e1]-(n6)-[:e2]-(n7)-[:e3]-(n8)
| | | |
[:ew] [:ex] [:ey] [:ez]
| | | |
(n?)-[:e3]-(n!)-[:e3]-(n&)-[:e3]-(n$)
. . . .
: : : :
I can write a query for exactly 8, 12 or 16... nodes, that are connected in this way. But I would like to write it more general to get the longest connected components, that are knitted like this.
Can you give me a hint, how to go along with that, because I'm totally new to neo4j?

Related

Visualising the motion of multiple robots

I am trying to add multiple robot instances and visualising their motions. I tried a couple of ways to do this and I ran into errors/issues. They are as follows:
I tried adding another model instance after the system is created.
parsers::urdf::AddModelInstanceFromUrdfFileToWorld(
FindResourceOrThrow("path/CompassGait.urdf"),
multibody::joints::kRollPitchYaw, tree.get());
parsers::urdf::AddModelInstanceFromUrdfFileToWorld(
FindResourceOrThrow("path/quadrotor.urdf"),
multibody::joints::kRollPitchYaw, tree.get());
As expected, there are two robots which are visible in the visualiser and there are 26 output ports in the system. But i am unable to visualise the required motion by the quadrotor. It seems to be following the x,y,z and roll pitch and yaw derivatives given as an input for the compass gait's output port. Is this an expected behaviour?
I experience a similar thing when I add 2 compass gait models and try to make them follow the same path. Even though I give the ports 14-27 the same inputs as i give to 0-13. The second robot is stuck near the origin while the first one moves fine as expected without any issues.
I needed some help or maybe some examples where I can get a better idea about visualising the motion for multiple robots.
[Updated] Please see note at the bottom.
drake::systems::DrakeVisualizer (which I assume you're using to publish your visualization messages) was designed to be connected to the state_output_port of drake::systems::RigidBodyPlant. According to the documentation for RigidBodyPlant,
The state vector, x, consists of generalized positions followed by generalized velocities.
That is, the generalized positions for all model instances come before the generalized velocities. When working with RigidBodyPlant and DrakeVisualizer this ordering is handled automatically.
From your question, however, I gather that you have separate, specialized systems for your quadrotor and compass-gait models (as per their respective examples). Each of these systems outputs its state as [q, v], where q is the generalized position vector and v is the generalized velocity vector. In that case you will need to use drake::systems::Demultiplexer and drake::systems::Multiplexer to split the outputs of the quadrotor and compass-gait systems and reassemble them in the required order:
+---------------+ +-------------+ q +-------------+
| | | +-------->+ |
| Compass-gait +-->+Demultiplexer| | |
| | | +-----+ v | |
+---------------+ +-------------+ | | |
+----->+ | +-----------------+
| | | | | |
| | | Multiplexer +-->+ DrakeVisualizer |
q| | | | | |
| +-->+ | +-----------------+
+---------------+ +-------------+ | | |
| | | +--+ | |
| Quadrotor +-->+Demultiplexer| | |
| | | +---+---->+ |
+---------------+ +-------------+ v +-------------+
Note: RigidBodyPlant and associated classes are being replaced by drake::multibody::MultibodyPlant and drake::geometry::SceneGraph. See run_quadrotor_lqr.cc for an example of using these new tools with a specialized plant.

Behave - Common features between applications, avoiding duplication

I have many applications which I want to test, which have a largely overlapping set of features. Here is an oversimplified example of a scenario I might have:
Given <name> is playing a game,
When they shoot at a <color> target
Then they should <event>
Examples:
| name | color | event |
| Alice | red | hit |
| Alice | blue | miss |
| Bob | red | miss |
| Bob | blue | hit |
| Bob | green | hit |
It's a silly example, but suppose really I have a lot of players with different hit/miss conditions, and I want to run just the scenarios for a given name? Say, I only want to run the tests for Alice. There's still advantage to having all the hit/miss tests in a single Scenario Outline (since, after all, they're all closely related).
One approach would be to just duplicate the test for every name and tag them, so something like:
#Alice
Given Alice is playing a game
When she shoots at a <color> target
Then she should <event>
Examples:
| color | event |
| red | hit |
| blue | miss |
This way I can run behave --tags #Alice, But then I'm repeated the same scenario for every user, and that's a lot of duplication. Is there a good way to still compress all the examples into one scenario - but only selectively run some of them? What's the right approach here?
Version 1.2.5 introduced better ways to distinguish scenario outlines. It is now possible to uniquely distinguish them and thus select a unique scenario generated from an outline with --name= at the command line. For instance, suppose the following feature file:
Feature: test
Scenario Outline: test
Given <name> is playing a game,
When they shoot at a <color> target
Then they should <event>
Examples:
| name | color | event |
| Alice | red | hit |
| Alice | blue | miss |
| Bob | red | miss |
| Bob | blue | hit |
| Bob | green | hit |
Let's say I want to run only the test for Bob, red, miss. It is in the first table, 3rd row. So:
behave --name="#1.3"
will select this test. In version 1.2.5 and subsequent versions. A generated scenario gets a name which includes "#<table number>.<row number>" where <table number> is the number of the table (starting from 1) and <row number> is the number of the row.
This won't easily allow you to select all scenarios that pertain to a single user. However, you can achieve it in another way. You can split your examples in two:
Examples: Alice
| name | color | event |
| Alice | red | hit |
| Alice | blue | miss |
Examples: Bob
| name | color | event |
| Bob | red | miss |
| Bob | blue | hit |
| Bob | green | hit |
The table names will appear in the generated scenario names and you could ask behave to run all the tests associated with one table:
behave --name="Alice"
I do not know of a way to access the example name in steps and thus get rid of the first column.
The full set of details is in the release notes for 1.2.5.

Extremely slow weighted-edge query in Neo4j

I have a graph with about 1.2 million nodes, and roughly 3.85 million relationships between them. I need to find the top x weighted edges - that is to say, the top x tuples of a, b, n where a and b are unique pairs of vertices and n is the number of connections between them. I am currently getting this data via the following Cypher query:
MATCH (n)-[r]->(x)
WITH n, x, count(r) as weight
ORDER BY weight DESC
LIMIT 50
RETURN n.screen_name, r.screen_name, weight;
This query takes about 25 seconds to run, which is far too slow for my needs. I ran the query with the profiler, which returned the following:
ColumnFilter(0)
|
+Extract
|
+ColumnFilter(1)
|
+Top
|
+EagerAggregation
|
+TraversalMatcher
+------------------+---------+---------+-------------+------------------------------------------------------------------------------------------------+
| Operator | Rows | DbHits | Identifiers | Other |
+------------------+---------+---------+-------------+------------------------------------------------------------------------------------------------+
| ColumnFilter(0) | 50 | 0 | | keep columns n.twitter, x.twitter, weight |
| Extract | 50 | 200 | | n.twitter, x.twitter |
| ColumnFilter(1) | 50 | 0 | | keep columns n, x, weight |
| Top | 50 | 0 | | { AUTOINT0}; Cached( INTERNAL_AGGREGATE01a74d75-74df-42f8-adc9-9a58163257d4 of type Integer) |
| EagerAggregation | 3292734 | 0 | | n, x |
| TraversalMatcher | 3843717 | 6245164 | | x, r, x |
+------------------+---------+---------+-------------+------------------------------------------------------------------------------------------------+
My questions, then, are these:
1. Are my expectations way off, and is this the sort of thing that's just going to be slow? It's functionally a map/reduce problem, but this isn't that large of a data set - and it's just test data. The real thing will have a lot more (but be filterable by relationship properties; I'm working on a representative sample).
2. What the heck can I do to make this run faster? I've considered using a start statement but that doesn't seem to help. Actually, it seems to make it worse.
3. What don't I know here, and where can I go to find out that I don't know it?
Thanks,
Chris
You're hitting the database 6,245,164 in the first statement: MATCH (n)-[r]->(x).
It looks like what you're attempting to do is a graph global query -- that is, you're trying to run query over the entire graph. By doing this you're not taking advantage of indexing that reduces the number of hits to the database.
In order to do this at the level of performance you're needing, an unmanaged extension may be required.
http://docs.neo4j.org/chunked/stable/server-unmanaged-extensions.html
Also, a good community resource to learn about unmanaged extensions: http://www.maxdemarzi.com/
The approach here would be to create a REST API method that extends the Neo4j server. This requires some experience programming with Java.
Alternatively you may be able to run an iterative Cypher query that updates an aggregate count on each [r] between (n) and (x).

Neo4j cypher query to return relationship property and sum of all matching relationship properties

I'm trying to return a relationship property (called proportion) plus the sum of that property for all relationship matched by a Cypher query in Neo4j. I've gotten this far:
START alice=node(3)
MATCH p=(alice)<-[r:SUPPORTED_BY]-(n)
RETURN reduce(total=0, rel in relationships(p): total + rel.proportion), sum(r.proportion) AS total;
This returns:
+-----------------+
| reduced | total |
+-----------------+
| 2 | 2 |
| 1 | 1 |
+-----------------+
where I was expecting:
+-----------------+
| reduced | total |
+-----------------+
| 2 | 3 |
| 1 | 3 |
+-----------------+
As a beginner user of Cypher, I'm not really sure how to approach this query; I'm clearly not using reduce correctly. Any advice would be appreciated.
You need to use WITH to split up the query into two parts:
find the sum of all proportions, and pass that as bound name to the next part
find the individual proportions
.
START alice=node(3)
MATCH alice<-[r:SUPPORTED_BY]-()
WITH sum(r.proportion) AS total
MATCH alice<-[r:SUPPORTED_BY]-(other)
RETURN other.name, r.proportion, total

Trying to find a Google Spreadsheet formula or query for this example

A | B | C | D | E | F | G
name|num|quant|item|quant2
car | 5 | 100 |
| | |wheel| 4
| | |axel | 2
| | |engine|1
truck| 2 | 20 |
| | |wheel| 6
| | |bed | 1
| | | axel| 2
I need a formula which will do B*C*E. the tables look like this, so it needs to be something like
=b$2*c$2*e3 and then dragged.... and then the next set, b$6*c$6*e7 and dragged, etc but i want sure how to get the cieling sort of something. if b5 is empty, look at each above until it finds the one not filled.
I am trying to use this to get total quantity of parts per car, truck etc.... and then group by part.
I dont have a set of DB tables to do this, just a spreadsheet.
I had to add some additional information to resolve this.
I was thinking there would be a way to do a google script that would do this and update the file, but i couldnt seem to find it.
I first summed each group item:
=b$3*e4
and dragged for that grouping.
Then afterwards, i went to a selection of space and wrote up a query.
=query(D:F, "select D,sum(F) group by D")

Resources