OrientDB: UPDATE of adjacent vertex - orientdb

Background
I have a model represented by a graph in OrientDB. The model consists of a few classes, among others A and B. The classes are connected with a relation has as an edge from A to B. The edge also connects A to other classes:
A ---has--> B
A ---has--> C
Problem
I want to update a property of B if it has a has edge to an A with a given RecordID.
My Solution
Currently I am selecting the target/out vertex of all edges has that are of class B starting at a given RecordID. This works but feels like I am missing an easier solution to this.
UPDATE (SELECT expand(out('has')[#class = 'B']) FROM #11:1) SET prop = true
I also tried the following, which did not work as I expected:
UPDATE B SET prop = true WHERE in('has').#rid = #11:1
My Question
Is there a simpler solution than an UPDATE with SUBSELECT?

I don't think there is any premade sql function that does this kind of filtering in an update.
Your first query is the way to go because it traverses instead of filtering on all the vertices. Yes, you have a subquery but it is faster then using a where in the update statement.
It would be cool to have a syntax like this :
update #9:1.inV('edgeClassName')[#class='className'] set prop = true
We have to use a subquery for this to work. It feels natural to me.

Related

Database Multiple Optional Filters with Null values in AnyLogic

I am trying to find the most optimal way to create conditional filtering of a Database in AnyLogic. The database, looks as follows:
What I am trying to do is adding in AnyLogic Main window 12 check boxes: P1, P2, P3, ..., T5, T6
If the user checks P1, with reference to the above table, A and B need to be displayed.
If the user checks P2, C needs to be displayed
If the user checks P1 and T2, A needs to be discplayed
In summary, it is like filtering in Excel any set of columns by "x" noting that the other cells have a null value.
To start, I used the following code to filter for P1 only (adding the entries to a collection of type String):
collectionDescription.addAll(
selectFrom( data_base ).
where( data_base.P1.eq("x")).
list( data_base.Col1));
Now to filter for P2 as well, the following can be done:
collectionDescription.addAll(
selectFrom( data_base ).
where( data_base.P1.eq("x")).
where( data_base.P2.eq("x")).
list( data_base.Col1));
Following the above logic, as many "where" conditions as needed can be added. However, there are so many possible combinations (e.g. P1/P2, P1/P2/P3, P1/P3, etc. you can imagine the amount of possible combinations).
So, I thought of a potential solution where I would add as many "where" conditions as there are columns, but instead of adding ".eq("x")", I would add ".eq(varP1)". If a checkbox (e.g. P1) is ticked, varP1 would be equal to "x" (varP1 being a variable of type String). But if the box is unticked, ideally varP1 should take a value that means "where anything" so that the condition would not make any impact. I did not manage to find a way to mimic this behavior.
Sorry for the long post, but I wanted to make sure the situation is as clear as possible. So am I on the right track? Any suggestions on how to fix this? Your suggestions would be highly appreciated.
let's say you have a checkbox associated to a variable varP1 to define what you want... then you can do
selectFrom(db_table)
.where(varP1 ? db_table.db_column.eq("x") : db_table.db_column.isNotNull().or(db_table.db_column.isNull()))
.list();
where anything is what i here did as any value which is either null or not null... so if the box is checked then you will find x, otherwise you will find anything

merge features n time

Here is my issue, I'm working on a project of water supply where I have to merge line features representing pipes if they have the same material of construction and if they are touching each other. The merge is done two by two what it means that some features will be duplicated in some cases like described in the figure below :
this shows exactly my issue. After the merge I will get three records but what I want is just one record which encompasses the whole pipes that fill the conditions put in the where clause :
Here is the query that helps me do the merge :
drop table if exists touches_material;
create table touches_material as
select distinct a.*,
st_Union(a.geom,b.geom) as fusion from pipe a, pipe b
where a.id < b.id and a.material = b.material and
st_touches(a.geom,b.geom)
group by a.id,a.geom,b.geom
the following picture picture shows the expected result on a test data, it's realized via QGIS GIS software :
but this is what I' getting with my query :
if you have any idea about how to achieve the aim that I invoked, I would be very thankful to get an answer from you. Best regards.

Gremlin query to find the count of a label for all the nodes

Sample query
The following query returns me the count of a label say
"Asset " for a particular id (0) has >>>
g.V().hasId(0).repeat(out()).emit().hasLabel('Asset').count()
But I need to find the count for all the nodes that are present in the graph with a condition as above.
I am able to do it individually but my requirement is to get the count for all the nodes that has that label say 'Asset'.
So I am expecting some thing like
{ v[0]:2
{v[1]:1}
{v[2]:1}
}
where v[1] and v[2] has a node under them with a label say "Asset" respectively, making the overall count v[0] =2 .
There's a few ways you could do it. It's maybe a little weird, but you could use group()
g.V().
group().
by().
by(repeat(out()).emit().hasLabel('Asset').count())
or you could do it with select() and then you don't build a big Map in memory:
g.V().as('v').
map(repeat(out()).emit().hasLabel('Asset').count()).as('count').
select('v','count')
if you want to maintain hierarchy you could use tree():
g.V(0).
repeat(out()).emit().
tree().
by(project('v','count').
by().
by(repeat(out()).emit().hasLabel('Asset')).select(values))
Basically you get a tree from vertex 0 and then apply a project() over that to build that structure per vertex in the tree. I had a different way to do it using union but I found a possible bug and had to come up with a different method (actually Gremlin Guru, Daniel Kuppitz, came up with the above approach). I think the use of project is more natural and readable so definitely the better way. Of course as Mr. Kuppitz pointed out, with project you create an unnecessary Map (which you just get rid of with select(values)). The use of union would be better in that sense.

using UPSERT create edges but in vertex class it shows nothing in Orientdb

UPDATE GeoAgentSummary set out = #45:0, in = #21:0, _2015 = sum(_2015, 10.0f) upsert where out = #45:0 and in = #21:0
I am using the above query to either create an edge (if it is not there) or update an existing edge if it already exists in OrientDB
An edge is created between #45:0 and #21:0.
But in Agent(vertex class having clusters 45, 46, 47 and 48) i.e. in #45:0 it is not showing any outgoing edges.
Agent Class a vertex class
I know that this question is three years old, but for somebody else who will google it further:
You can use “upsert” for edges since version 3.0.1 and it will work properly – but you need to do the following:
Create unique index on edge_class (out, in) and – it's strange – The order is important!
To do this, you need to create in and out properties first, otherwise db can't create index and there will be an exception when you will try to run command “Create index”.
Then, use command CREATE EDGE UPSERT FROM TO .
In this case edge will be created only if it is not exists, and it will create in and out properties for vertex classes.
But it still doesn't work for UPDATE command 'cos, as authors said, “The UPDATE/UPSERT works at document level, so it doesn't create the connections from the vertices. Using it, you will have a broken graph” and it still the same.
The UPDATE command acts like a normal document update without taking care of keeping the edge-vertex "synchronization". To do that you'd have to use the UPDATE EDGE that, however, doesn't support the UPSERT.
There is on open issue on github about that https://github.com/orientechnologies/orientdb/issues/4436
Read also this https://github.com/orientechnologies/orientdb/issues/1114

How to put together two queries?

In the title is what I need.
CREATE TABLE newTable1 AS SELECT t2.name,t2.the_geom2
FROM t1,t2
WHERE ST_Contains(ST_Expand(t2.the_geom2,0.05),t1.the_geom1)
and t1.gid=2;
CREATE TABLE newTable2 AS SELECT t1.the_geom,t1.label FROM t1 WHERE t1.gid=2;
First query result is all points within polygon and apart from it for 5min where this polygon has gid=2. But I also want to display this polygon. I tried to write in first query
... AS SELECT t2.name,t2.the_geom2,t1.the_geom1,t1.label ...but got only points without polygon...
This question is linked with already asked question "How to find all points away from some polygon?". But didn't get answere, so please...
And is ST_expand ok solution or it will be better to use ST_DWithin or ST_buffer ?
You can't combine two CREATE TABLE statements into one. Why are you creating tables if you are just querying data?
It sounds like what you are really trying to do is one query that will give you the points within the polygon and the polygon itself. Something like this?
SELECT
t1.the_geom AS polygon, t1.label AS polygon_label,
t2.the_geom2 AS point, t2.name AS point_name
FROM
t1, t2
WHERE
ST_Contains(ST_Expand(t2.the_geom2,0.05), t1.the_geom1)
AND t1.gid = 2;
If this is still not clear, post your complete table definitions and more details about what you are trying to do.