SQL query to include V and E props in the result - orientdb

I feel like this should be simple, but lots of searching and experimenting has not produced any results.
I have a very simple ODB database with one V and one E class. V has various props and E has one prop: "order"
This simple ODB SQL query...
select expand(out()) from #12:34
...returns all the props from the V records connected by the "out" edges on #12:34 (i.e. the child records of #12:34), working as expected.
But what I'm not able to do is to also include the one prop from those edges, as well as sort by that E prop (which should be trivial once I can get it into the projections).

This works fine in OrientDB v 3.0.0RC2 (the GA will be released in a few days)
MATCH
{class:V, where:(#rid = ?), as:aVertex}.outE(){as:theEdge}.inV(){as:otherVertex}
RETURN theEdge:{*}, otherVertex:{*}
you can also return single properties with
RETURN theEdge.prop1 as p1, theEdge.prop2 as p2, otherVertex.propX as p3

Related

Is it possible to return a map of key values using gremlin scala

Currently i have two gremlin queries which will fetch two different values and i am populating in a map.
Scenario : A->B , A->C , A->D
My queries below,
graph.V().has(ID,A).out().label().toList()
Fetch the list of outE labels of A .
Result : List(B,C,D)
graph.traversal().V().has("ID",A).outE("interference").as("x").otherV().has("ID",B).select("x").values("value").headOption()
Given A and B , get the egde property value (A->B)
Return : 10
Is it possible that i can combine both there queries to get a return as Map[(B,10)(C,11)(D,12)]
I am facing some performance issue when i have two queries. Its taking more time
There is probably a better way to do this but I managed to get something with the following traversal:
gremlin> graph.traversal().V().has("ID","A").outE("interference").as("x").otherV().has("ID").label().as("y").select("x").by("value").as("z").select("y", "z").select(values);
==>[B,1]
==>[C,2]
I would wait for more answers though as I suspect there is a better traversal out there.
Below is working in scala
val b = StepLabel[Edge]()
val y = StepLabel[Label]()
val z = StepLabel[Integer]()
graph.traversal().V().has("ID",A).outE("interference").as(b)
.otherV().label().as(y)
.select(b).values("name").as(z)
.select((y,z)).toMap[String,Integer]
This will return Map[String,Int]

Combine Records in Purescript

Given I have the folowing records in purescript:
let name = {name: "Jim"}
let age = {age: 37}
is it possible to combine those two records some how in a generic way?
Something like:
name 'comb' age
such that I get the following record:
{name: "Jim", age: 37}
Somehow it seems to be possible with the Eff rowtype, but I'm curious if it would be possible with 'normal' records. I'm new to purescript and it's record syntax.
Thanks a lot.
EDIT:
It seems that currently the official package for handling record manipulations is purescript-record - you can find Builder.purs there which provides merge and build functions:
> import Data.Record.Builder (build, merge)
> name = {name: "Jim"}
> age = {age: 37}
> :t (build (merge age) name)
{ name :: String
, age :: Int
}
API NOTE:
This API looks overcomplicated at first glance - especially when you compare it to simple unionMerge name age call (unionMerge is intoduced at the end of this answer). The reason behind Builder existence (and so this API) is performance. I can assure you that this:
> build (merge name >>> merge age) {email: "someone#example.com"}
creates only one new record. But this:
> unionMerge name (unionMerge age {email: "someone#example.com"})
creates two records during execution.
What is even more interesting is how Builder, build and merge are implemented - Builder is newtype wrapper around a function (and its composition is just a function composition) and build is just a function application on copied version of the record:
newtype Builder a b = Builder (a -> b)
build (Builder b) r1 = b (copyRecord r1)
In merge there is unsafeMerge performed:
merge r2 = Builder \r1 -> unsafeMerge r1 r2
So why are we gaining here anything?? Because we can be sure that intermediate results can't escape function scope and that every value is consumed exactly once in builder chain. Therefore we can perform all transformations "in place" in a mutable manner. In other words this intermediate value:
> intermediate = unionMerge name {email: "someone#example.com"}
> unionMerge age intermediate
can't be "extracted" from here:
> build (merge name >>> merge age) {email: "someone#example.com"}
and it is only consumed once by the next builder, namely merge age.
TYPESYSTEM COMMENT:
It seems that Purescript type system can handle this now thanks to the Union type class from Prim:
The Union type class is used to compute the union of two rows
of types (left-biased, including duplicates).
The third type argument represents the union of the first two.
Which has this "magic type" (source: slide 23):
Union r1 r2 r3 | r1 r2 -> r3, r1 r3 -> r2
OLD METHOD (still valid but not preferred):
There is purescript-records package which exposes unionMerge which does exactly what you want (in new psci we don't have to use let):
> import Data.Record (unionMerge)
> name = {name: "Jim"}
> age = {age: 37}
> :t (unionMerge age name)
{ name :: String
, age :: Int
}
note: When this answer was accepted, it was true, but now we do have the row constraints it mentions, and a library for manipulating records that includes merges/unions: https://github.com/purescript/purescript-record
It's not possible to do this at the moment, as we don't have a way of saying that a row lacks some label or other. It is possible to have an open record type:
something :: forall r. { name :: String | r } -> ...
But this only allows us to accept a record with name and any other labels, it doesn't help us out if we want to combine, extend, or subtract from records as it stands.
The issue with combining arbitrary records is we'd have a type signature like this:
comb :: forall r1 r2. { | r1 } -> { | r2 } -> ???
We need some way to say the result (???) is the union of r1 and r2, but also we'd perhaps want to say that r1's labels do not overlap with r2's.
In the future this may be possible via row constraints.

FlinkML: Joining DataSets of LabeledVector does not work

I am currently trying to join two DataSets (part of the flink 0.10-SNAPSHOT API). Both DataSets have the same form:
predictions:
6.932018685453303E155 DenseVector(0.0, 1.4, 1437.0)
org:
2.0 DenseVector(0.0, 1.4, 1437.0)
general form:
LabeledVector(Double, DenseVector(Double,Double,Double))
What I want to create is a new DataSet[(Double,Double)] containing only the labels of the two DataSets i.e.:
join:
6.932018685453303E155 2.0
Therefore I tried the following command:
val join = org.join(predictions).where(0).equalTo(0){
(l, r) => (l.label, r.label)
}
But as a result 'join' is empty. Am I missing something?
You are joining on the label field (index 0) of the LabeledVector type, i.e., building all pairs of elements with matching labels. Your example indicates that you want to join on the vector field instead.
However, joining on the vector field, for example by calling:
org.join(predictions).where("vector").equalTo("vector"){
(l, r) => (l.label, r.label)
}
will not work, because DenseVector, the type of the vector field, is not recognized as key type by Flink (such as all kinds of Arrays).
Till describes how to compare prediction and label values in a comment below.

Postgis using contains and count even if answer is 0

I have a problem with the count function...
I want to isolate all polygons laying beside G10 polygon and I want to count number of points (subway stations) in my polygons (neighborhoods) but i want to receive an answer even if that answer must be 0.
I used the following statement :
select a2.name, count(m.geom)
from arr a1, arr a2, metro m
where n1.code='G10'
and ((st_touches(a1.geom, a2.geom)) or
(st_overlaps(a1.geom, a2.geom)))
and ST_Contains(a2.geom, s.geom)
group by a2.name, m.geom
I know the problem lies with the and ST_Contains(a2.geom, s.geom) part of the where clause, but I do not now how to solve it!
Use an explicit LEFT JOIN:
SELECT a1.name, COUNT(a2.code)
FROM arr a1
LEFT JOIN
arr a2
ON ST_Intersects(a1.geom, a2.geom)
WHERE a1.code = 'G10'
I'm not including the other tables as you have obvious typos in your original query and it's not clear how should they be connected

Entity Framework - TOP using a dynamic query

I'm having issues implementing the TOP or SKIP functionality when building a new object query.
I can't use eSQL because i need to use an "IN" command - which could get quite complex if I loop over the IN and add them all as "OR" parameters.
Code is below :
Using dbcontext As New DB
Dim r As New ObjectQuery(Of recipient)("recipients", dbcontext)
r.Include("jobs")
r.Include("applications")
r = r.Where(Function(w) searchAppIds.Contains(w.job.application_id))
If Not statuses.Count = 0 Then
r = r.Where(Function(w) statuses.Contains(w.status))
End If
If Not dtFrom.DbSelectedDate Is Nothing Then
r = r.Where(Function(w) w.job.create_time >= dtDocFrom.DbSelectedDate)
End If
If Not dtTo.DbSelectedDate Is Nothing Then
r = r.Where(Function(w) w.job.create_time <= dtDocTo.DbSelectedDate)
End If
'a lot more IF conditions to add in additional predicates
grdResults.DataSource = r
grdResults.DataBind()
If I use any form of .Top or .Skip it throws an error : Query builder methods are not supported for LINQ to Entities queries
Is there any way to specify TOP or Limit using this method? I'd like to avoid a query returning 1000's of records if possible. (it's for a user search screen)
Rather than
r = new ObjectQuery<recipient>("recipients", dbContext)
try
r = dbContext.recipients.
.Skip() and .Take() return IOrderedQueriable<T> while .Where returns IQueriable<T>. Thus put the .Skip() and .Take() last.
Also change grdResults.DataSource = r to grdResults.DataSource = r.ToList() to execute the query now. That'll also allow you to temporarily wrap this line in try/catch, which may expose a better message about why it's erroring.
Mark this one down to confusion. I should have been using the .Take instead of .Top or .Limit or anything.
my final part is the below and it works :
grdResults = r.Take(100)