OrientDB not able to create multiple edges between same nodes - orientdb

I want to create multiple relationships between node A and node B using a single edge, but the relationship to contain different properties.
Edge:
EPartner (description, relationdate, type, weight)
What I have tried:
CREATE EDGE EPartner FROM #rid TO #rid CONTENT 'something'
The above line is working when I create the first relationship, but when I try to add a new relation between same source and same target, the previous record is replaced with the new one.
I'm expecting to have multiple records on the same edge, with same target and source, just with different properties.
Is this possible ? Please give me some hints about what to try out.

Just tried to verify your case. Unfortunately, without declaring constrains on the edge, everything works as expected.
This is a log of my experiment (active-orient console)
2.6.3 :001 > V.create_class :test
=> Test
2.6.3 :002 > E.create_class :test_edge
=> TEST_EDGE
2.6.3 :003 > t = Test.create name: :test
16.08.(03:46:15) INFO->CREATE VERTEX test set name = ':test:'
2.6.3 :004 > t1 = Test.create name: :test2
16.08.(03:46:28) INFO->CREATE VERTEX test set name = ':test2:'
2.6.3 :005 > t.assign vertex: t1, via: TEST_EDGE, attributes: { edge_count: 'first' }
16.08.(03:46:42) INFO->CREATE EDGE test_edge from #29:0 to #30:0 content {"edge_count":"first"}
2.6.3 :006 > t.assign vertex: t1, via: TEST_EDGE, attributes: { edge_count: 'second' }
16.08.(03:46:48) INFO->CREATE EDGE test_edge from #29:0 to #30:0 content {"edge_count":"second"}
2.6.3 :007 > t.reload!
2.6.3 :008 > t.out.to_human
=> ["<TEST_EDGE[#35:0] :.: 29:0->{ edge_count: first }->30:0>",
"<TEST_EDGE[#36:0] :.: 29:0->{ edge_count: second }->30:0>"]
Provided two edges between the vertices.

Related

Editing the labels on a flow chart with DiagrammeR

I’m trying to make a flow chart with R. Attached is the chart I made in word (which is what I'm trying to get to). I don’t want to copy and paste it, I want to actually make it in R. I’ve been using DiagrammeR to try, and the code is below.
I'm having the main trouble with the labels, how to change some parts to bold and make them a nice distance away from the nodes. I've added in the blue and pink boxes in my code, which I like.
Code:
library(DiagrammeR)
graph <- "
digraph boxes_and_circles{
# Add node statements
# This states that all following nodes have a box shape
node[
shape=box,
style=rounded,
fontname=Helvetica,
penwidth=2,
fixedsize = true
width=4
]
# Connect the nodes with edge statements
edge[
arrowhead = normal,
arrowtail = none
]
# These are the main nodes at top of graph
'##1'->'##2'
[label=' Cleaning Function:
Text to lower case
Contractions expanded
Numbers replaced
Abbreviations expanded (Qdap)
NA’s ignored
Kerns replaced
White space removed', fontname=Helvetica, fontsize=20, fontweight=bold]
'##2'->'##3'
'##2'->'##4'
# Make subnodes with boxes around for tidy text grouping
# graph, node, and edge definitions
graph [
compound = true,
nodesep = 1,
ranksep = 0.25,
color = pink
]
# subgraph for tidy text, direct the flow
subgraph cluster0 {
'##3'->'##5'
[label=' -Tokenization
-Lemetisation
-Stop words removed', fontname=Helvetica, fontsize=20, fontweight=bold]
}
# Make subnodes with boxes around for Dictionary grouping
# graph, node, and edge definitions
graph [
compound = true,
nodesep = 1,
ranksep = .25,
color = blue
]
# subgraph for Dictionary direct the flow
subgraph cluster1 {
node [
fixedsize = true,
width = 3
]
'##4'->'##6' [label=' Scoring function (sentimentr)
Inner Join (dplyr)',fontname=Helvetica]
'##6'->'##7' [label=' Grouping
Summarise (dplyr)',fontname=Helvetica]
'##7'->'##8'
}
#Add a graph statement to change the properties of the graph
graph[nodesep=1] #this modifies distance between nodes
}
# Name the nodes
[1]: 'Response Data'
[2]: 'Clean Data'
[3]: 'Tidy Text'
[4]: 'Dictionary Creation'
[5]: 'Visualisation'
[6]: 'Sentiment Lexicon'
[7]: 'Summarised Text'
[8]: 'Visualisation and Statistics'
"

How to avoid moving child object when parent is moved?

Is it possible to avoid moving inline child objects of parent when parent record is moved?
My use case:
There is TYPO3 record (parent) of type X which has inline relation to record of type Y (child).
Following configuration is loaded:
TCAdefaults.Y {
pid = 129
}
I am adding new X record on page 1 and inline relation of type Y. X
is created with pid = 1 and Y is created with pid = 129. So far
good.
Now I am moving record X to page 2. Both X and Y have pid 2 now. How can
I avoid that? I don't want inline record Y to change pid when X is moved in backend (example cut and paste functionality).
There is a TCA configuration for this purpose. Add this to your TCA inline field configuration:
'behavior' => [
'disableMovingChildrenWithParent' => true
],
The docs: https://docs.typo3.org/typo3cms/TCAReference/ColumnsConfig/Type/Inline.html#disablemovingchildrenwithparent

Orientdb - Traverse based on a specific edge field

In the figure below each vertex is connected to others with edges of class E_FIELD. Each edge has a field called propName. Starting from a vertex I need to traverse through edges with propName set a specific value. In the figure below, I need to start from vertex 1 and traverse through the edges which have 'place' as their propName fields (going from 1 to 2 and then to 3). It should exclude vertex 4 as its propName is not set to place. How can I do this?
The following query should help you in your quest:
SELECT FROM (TRAVERSE * FROM <your_vertex_rid>) WHERE #class = "E_FIELD" AND propName = "place"

Tinkerpop Frames: Get Edge when adding a vertex

i followed the example on https://github.com/tinkerpop/frames/wiki/Getting-Started and wanted to do the following: When adding a new Project, for example
marko.addCreatedProject(pr);
i also want to get the edge between marko and pr to set the weight, for example. One way to do this is to get all outgoing vertices of marko and find pr in the list of vertices. Is there a better way to do this? Is it possible to return the edge, when i call addCreatedProject, to do the following:
CreatededInfo cr = marko.addCreatedProject(pr);
cr.setWeight(3);
You could try using the addEdge method on FramedGraph which returns the Edge when you supply two vertices to relate. So a little more fine grained.
E.g.
com.tinkerpop.frames.FramedGraphFactory.FramedTransactionalGraph graph = ...
Vertex user1 = graph.addVertex(null);
Vertex project1 = graph.addVertex(null);
Edge newEdge = graph.addEdge(null, user1, project1, "CREATED");
// ... do something with newEdge
The tinkerpop FramedGraph interface also has overloaded methods for addVertex and addEdge, so that you can supply your framed Class type, to have a Framed vertex or edge returned which can be convenient.
E.g.
Vertex user1 = graph.addVertex(null, Person.class);
Vertex project1 = graph.addVertex(null, Project.class);
Edge newEdge = graph.addEdge(null, user1, project1, "CREATED",Direction.OUT, MyEdge.class);
And of course you can graph.frame(newEdge, MyEdge.class) after the fact too, if you only have a com.tinkerpop.blueprints.Edge.
Here is the Javadoc for FramedGraph

How to find LINESTRINGs that touch in a begin/ending node

In PostGIS you can intersect two geometries using:
geometry ST_Intersection (geometry geomA, geometry geomB);
In my case both geomA and geomB are LINESTRING so ST_Intersection() returns a POINT geometry.
I want to know if the intersection occurs in a begin/end node (the geometries touch) or in the middle (the geometries intersect).
I can compare the (Point.X, Point.Y) with each ending node:
geomA.nodes(0) - geomA.nodes(len-1)
geomB.nodes(0) - geomB.nodes(len-1)
But is very complex. And I would like a simple solution.
There are 3 intersect cases.
Example 1: Two lines in a "L" shape intersect in an end node on both lines on the bottom left.
Example 2: Two lines in a "T" shape where the vertical line intersects in the middle of the horizontal line. In this case the vertical line end node touches a non-end node of the horizontal line.
Example 3: Two lines in a "X" shape. Intersection point isn't an end node for either line.
For my problem I'm only interested in finding the touching scenario like Example 2.
NOTE
This is the pseudo code I use now.
geomM, geomN Linestring
a, b, c, d, z Points.
(a,b) begin/end node for geomM ST_StartPoint(geom) and ST_EndPoint(geom)
(c,d) begin/end node for geomN
z = ST_Intersect(geomM, geomN)
SELECT geomM, geomN, z
FROM Table
WHERE
(A and not ( B or C or D))
OR (B and not ( A or C or D))
OR (C and not ( A or B or D))
OR (D and not ( A or B or C))
A, B, C, D replace ( a=z ) ( b=z ) ( c=z ) ( d=z )
This mean one node {a,b,c,d} is equal to intersection z. But only one
This return all "T" shape intersections.
You need the PostGIS function ST_Touches() here. The function returns true if the geometries touch on their boundaries, but false if they intersect. In terms of your examples, Example 1 and 2 return true, Example 3 returns false.
Relaxed solution
To select the IDs of all pairs of touching geometry(LINESTRING, xxx) records from a single table use this:
SELECT x.id AS idA, y.id AS idB
FROM my_table x
JOIN my_table y ON ST_Touches(y.the_geom, x.the_geom)
WHERE x.id < y.id;
(The WHERE clause avoids duplicate results like (132, 254) and (254, 132).)
Note that the linestrings can also touch on any of their non-node vertices. If you want to strictly follow Example 2 then you have to compare every point on every linestring against every point on all other linestrings, which is obviously going to be a very intensive operation. Example 2 is basically only feasible when you know that the linestrings are very short, preferably just straight lines.
Strict solution, straight lines only
If all LINESTRINGs are straight, i.e. composed of a starting and an ending node only, then this is your solution:
SELECT h.id AS touched, v.id AS touching, ST_Intersection(h.the_geom, v.the_geom) AS touch_point
FROM my_table h -- "horizontal" T bar, being touched
JOIN my_table v ON -- "vertical" T bar, touching
(
-- The "vertical" start node touches, but not on either of the "horizonal" nodes
ST_Equals(ST_Intersection(h.the_geom, v.the_geom), ST_StartPoint(v.the_geom))
AND NOT ST_Equals(ST_StartPoint(h.the_geom), ST_StartPoint(v.the_geom))
AND NOT ST_Equals(ST_EndPoint(h.the_geom), ST_StartPoint(v.the_geom))
) OR (
-- The "vertical" end node touches, but not on either of the "horizonal" nodes
ST_Equals(ST_Intersection(h.the_geom, v.the_geom), ST_EndPoint(v.the_geom))
AND NOT ST_Equals(ST_StartPoint(h.the_geom), ST_EndPoint(v.the_geom))
AND NOT ST_Equals(ST_EndPoint(h.the_geom), ST_EndPoint(v.the_geom))
);
All the requirements are checked in the JOIN ON clause. This will also return the location where the "vertical" bar of the T touches the "horizontal" bar. Note that the conditions are short-circuited when being evaluated and repeated calls to a function with the same input data are optimized to a single call.