Querying Orient DB with 'joins' - orientdb

I've recently started looking at OrientDB coming from a relational background (Oracle RDBMS) and I'm struggling to query some data I've loaded into OrientDB.
I have 2 classes:
CREATE CLASS prices
CREATE PROPERTY prices.price_created_datetime DATETIME
CREATE PROPERTY prices.price_value DOUBLE
CREATE CLASS stocks
CREATE PROPERTY stocks.stock_symbol STRING
CREATE PROPERTY stocks.stock_prices LINKLIST prices
I'm loading some data by first running an UPSERT on the 'stocks' class, and then several times over the day adding prices:
UPDATE stocks ADD stock_prices = {json string of class:prices}
What I'd like to do is get all stocks.stock_symbol values and aggregate (using average) the prices.price_value within the last 24 hours (therefore filtering on prices.price_created_datetime).
I'm using the web based studio and I've toyed with a few different methods but I'm struggling to get the concept when most of my queries return nothing. I have OrientDB 2.1.9 running embedded in a Java application.
Any help would be appreciated.

I tried your case with this structure (like yours):
Class: stocks
Property: stocks.stock_symbol STRING
Property: stocks.stock_prices LINKLIST prices
Class: prices
Property: prices.price_created_datetime DATETIME
Property: prices.price_value DOUBLE
And here's the data:
To find all of stock symbols with relative prices average of the last 24 hours, I used this query:
select stock_symbol, $prices.averageLast24 as averagePricesLast24 from stocks
let $prices = (select avg(price_value) as averageLast24 from (select price_value, price_created_datetime.asDatetime() as dataLast24 from prices) where eval('(sysdate() - dataLast24) / 3600000') < 24 and dataLast24 in $parent.current.stock_prices.price_created_datetime)
unwind averagePricesLast24
and this is the output:
----+------+------------+-------------------
# |#CLASS|stock_symbol|averagePricesLast24
----+------+------------+-------------------
0 |null |bbb |492345.5
1 |null |ccc |320167.0
----+------+------------+-------------------
Hope it helps

Related

How to query a reference table for a value between a dates for a specified category in Apps Script?

I have a background in data analytics and have done a similar workflow in SQL but am brand new to Apps Script. I am a bit at a loss on where to even start in Apps Script. Any advice or pointing me in the direction of useful examples would be truly appreciated!
Currently, I have a reference table on one sheet with categories and values and the start and end date that value applies to. Then I have a data table on another sheet where I add an entry date and a category and I would like to have Apps Script write the corresponding value for that category on the date.
Reference table data (a blank end date means that is the current rate):
Category
Value
Start date
End date
A
25
01/01/2022
3/31/2022
B
40
01/01/2022
C
30
01/01/2022
A
15
04/01/2022
The data table where the entry date and the category are added manually over time. I want to use the reference table to write the value for that category for that entry date.
Entry Date
Category
Value
02/20/2022
B
40
02/27/2022
A
25
03/20/2022
A
25
04/16/2022
C
15
05/12/2022
A
30
06/02/2022
B
40
How do you get the query the reference data for that entry date and category to find the row with the corresponding value?
Description
As I said I'm not good at QUERY but I finally got something to work. I'm sure other can improve on it.
First I created a named range TestQuery for the table of data. I could have just as easily used range "A1:D6"
Next I fill in the End Date with =TODAY() so it has a date value. Then I build my query.
=QUERY(TestQuery,"select B where ( ( A = '"&B11&"' ) and ( date '"&TEXT(A11,"yyyy-mm-dd")&"' > C ) and ( date '"&TEXT(A11,"yyyy-mm-dd")&"' < D ) )")
Reference
Query Language
Compare Dates in Query
Getting data from a table on a sheet
function getData() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const values = sh.getRange("A2:D" + sh.getLastRow()).getValues();
Logger.log(JSON.stringify(values));//2d array
}
A2 is assumed to be the upper left corner of the data

Flask Mongoengine filter a query

I'm using Mongoengine in my flask application and I'm trying to filter a simple query.
My document name is Event and it has the following fields:
user (ReferenceDocument)
category (ReferenceDocument)
type (StringField)
start_time (DateField)
My goal is to get the last 30 events of given user, filter it based on category & type and then count the filtered results.
My attempt was:
grades = {}
events = Event.objects(user=user).order_by('-start_time')[:30]
for category in user.categories:
grade = 0
for event_type in eEvents:
grade += (events(category=category, type=event_type.name).count(
with_limit_and_skip=True)) * event_type.value
grades[category.name] = grade
So the problem is that the query (2nd line in code) doesn't limit the results and I get all the events of the user. When I use the count method after filtering the query, it does limit the count to 30.
By the way, any idea of a better way for doing it using mongoengine functionality?
Thanks

Group by date intervals using JPA's Criteria API

I'm trying to group entities by date intervals using JPA's Criteria API. I use this way of querying for entities as this is a part of the service that serves API requests which may ask for any field of any entity, including sorting, filtering, grouping and aggregations. Everything works fine except for grouping by date fields. My underlying DBMS i PostgreSQL.
To give a minimal example, here's my entity class:
#Entity
#Table(name = "receipts")
public class DbReceipt {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Date sellDate;
// Many other fields
}
This example discusses grouping my "month" interval (therefore grouping by year+month), but in the end I'm looking for a solution that would let me group by any interval, such as "year", "day" or "minutes".
What I'm trying to achieve is the following query, but using Criteria API:
SELECT TO_CHAR(sell_date, 'YYYY-MM') AS alias1 FROM receipts GROUP BY alias1;
My attempt to do so is this:
#Service
public class ReceiptServiceImpl extends ReceiptService {
#Autowired
private EntityManager em;
#Override
public void test() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
Root<?> root = query.from(DbReceipt.class);
Expression<?> expr = cb.function("to_char", String.class, root.get("sellDate"), cb.literal("YYYY-MM"));
query.groupBy(expr);
query.multiselect(expr);
TypedQuery<Object[]> typedQuery = em.createQuery(query);
List<Object[]> resultList = typedQuery.getResultList();
}
}
The reason I use to_char function and not MONTH and similar is that I need entities like 2019-05 and 2020-05 to not be grouped together. I also narrow this example down to only year and month to keep things short, but the goal is to group by any date interval.
The code above creates the following query (SQL logging enabled) which results in an error:
Hibernate: select to_char(dbreceipt0_.sell_date, ?) as col_0_0_ from receipts dbreceipt0_ group by to_char(dbreceipt0_.sell_date, ?)
24-05-2020 12:16:30.071 [http-nio-1234-exec-5] WARN o.h.e.jdbc.spi.SqlExceptionHelper.logExceptions - SQL Error: 0, SQLState: 42803
24-05-2020 12:16:30.071 [http-nio-1234-exec-5] ERROR o.h.e.jdbc.spi.SqlExceptionHelper.logExceptions - ERROR: column "dbreceipt0_.sell_date" must appear in the GROUP BY clause or be used in an aggregate function
Position: 16
which to me is caused by the fact that the whole expression is put into the 'group by' part of the query, rather than just an alias. Now, I've tried to assign an alias to the expression (which returns Selection<T> and groupBy accepts expressions, therefore I can only really use that in the multiselect), but that didn't affect how the query is performed - nothing changed.
How do I achieve grouping by year and month as described above using Criteria API? Maybe there's a different way other than using to_char? Maybe there's a way to give an alias to the groupBy method that would cause it to group by an alias instead of the whole expression?
I think it's a bug in PostgreSQL (the error comes from there, not from Hibernate). I have tried a slightly modified version of your code with EclipseLink + Derby and works perfectly.
Note that I had to use numbers instead of strings because Derby DB doesn't have an equivalent of TO_CHAR function.
Expression<Integer> year = cb.function("YEAR", Integer.class, root.get("sellDate"));
Expression<Integer> month = cb.function("MONTH", Integer.class, root.get("sellDate"));
Expression<Integer> expr = cb.sum(month, cb.prod(12, year));
query.groupBy(expr);
query.multiselect(expr);
This returns the following SQL:
SELECT (MONTH(MY_DATE) + (12 * YEAR(MY_DATE)))
FROM MY_DATE_TABLE
GROUP BY (MONTH(MY_DATE) + (12 * YEAR(MY_DATE)))
Note that there are no portable solutions for manipulating dates in JPA criteria queries. If the number of groups to be queried simultaneously is not too high I'd go with a more practical approach where you find the dates in Java and pass them as literals to the query builder.
Another workaround is to query with a groupBy(root.get("sellDate")) and then aggregate the results in Java according to the desired time period.
Post Scriptum: I don't think it's relevant, however I modified the query's return type from Object[] to Object.

Calculated Time weigthed return in Power BI

Im trying to calculate the Time Weigthed Return for a portfolio of stocks. The formula is:
I have the following data:
Im calculate the TWR (time weigthed return) in Power Bi as:
TWR = productx(tabel1;TWR denom/yield+1)
The grey and blue marked/selected fields are individual single stock. Here you see the TWR for the grey stock is = 0,030561631 and for the blue TWR = 0,012208719 which is correct for the period from 09.03.19 to 13.03.19.
My problem is, when im trying to calculate the TWR for a portfolio of the two stocks, it takes the product og every row. In the orange field I have calculated the correct result in excel. But in Power BI it takes the product of the grey and blue stocks TWR: (0,0305661631 * 0,012208719) = 0,03143468 which is incorrect.
I want to sum(yield for both stocks)/sum(TWRDenominator for both stocks) for both stocks every single date, such that I not end up with two rows (one for each stock) but instead a common number every date for the portfolio.
I have calculated the column TWR denom/yield -1 in a measure like this:
twr denom/yield-1 = CALCULATE(1+sumx(tabel1;tabel1(yield)/sumx(tabel1;tabel1[TwrDenominator])))
How can I solved this problem?
Thank you in advance!
This is one solution to your question but it assumes the data is in the following format:
[Date] | [Stock] | [TWR] | [Yield]
-----------------------------------
[d1] | X | 12355 | 236
[d1] | y | 23541 | 36
[d2] ... etc.
I.e. date is not a unique value in the table, though date-stock name will be.
Then you can create a new calculated table using the following code:
Portfolio_101 =
CalculateTable(
Summarize(
DataTable;
DataTable[Date];
"Yield_over_TWR"; Sum(DataTable[Yield])/Sum(DataTable[TWR_den])+1
);
Datatable[Stock] in {"Stock_Name_1"; "Stock_Name_2"}
)
Then in the new Portfolio_101 create a measure:
Return_101 =
Productx(
Portfolio_101;
Portfolio_101[Yield_over_TWR]
)-1
If using your data I en up with the following table, I have created three calculated tables, one fore each stock and a third (Portfolio_103) with the two combined. In addition I have a calendar table which has a 1:1 relationship between all Portfolio tables.
Hope this helps, otherwise let me know where I've misunderstood you.
Cheers,
Oscar

How to map a calculated value to a property?

I'm using Entity Framework to map database to a class in my application.
The class is automatically generated as partial class by EF and I also added some other properties in my own file to the same partial class.
I use these queries to get a list of entities from the table (they are equivalent as far as I can tell):
db.DailyEntry.ToList
db.DailyEntry.SqlQuery("SELECT * FROM DailyEntry").ToList
db.Database.SqlQuery(Of DailyEntry)("SELECT DailyEntry.DailyEntryId, DailyEntry.Driver, DailyEntry.Billing, DailyEntry.EntryDate FROM DailyEntry").ToList
I then added a field to this class:
Public Property IsHoliday As Boolean = False
I iterated through the list and calculated whether the date falls on a bank holiday. I have a database table of holidays:
For Each entry As DailyEntry in _myList_
entry.IsHoliday = db.Database.SqlQuery(Of Boolean)("SELECT IsHoliday FROM Holiday WHERE HolidayDate = {0}", entry.EntryDate).FirstOrDefault
Next
This all works fine but as the amount of records increased, so did the number of database calls and I need to speed the application up by merging these into a single call.
I modified the query to include the holiday info:
SELECT DailyEntry.*, Holiday.IsHoliday AS IsHoliday FROM DailyEntry LEFT OUTER JOIN Holiday ON DailyEntry.EntryDate = Holiday.HolidayDate;
or
SELECT DailyEntry.DailyEntryId, DailyEntry.Driver, DailyEntry.Billing, DailyEntry.EntryDate, Holiday.IsHoliday AS IsHoliday FROM DailyEntry LEFT OUTER JOIN Holiday ON DailyEntry.EntryDate = Holiday.HolidayDate;
and a few similar tries. They work well when I test them as queries on the database and return expected data, but when I try to use them in my app:
db.Database.SqlQuery(Of DailyEntry)("SELECT DailyEntry.*, Holiday.IsHoliday AS IsHoliday FROM DailyEntry LEFT OUTER JOIN Holiday ON DailyEntry.EntryDate = Holiday.HolidayDate").ToList
the IsHoliday property is always left at default value (False).
Is there a way to get these calculated columns that are not part of the original database table to map to my properties?
Thanks in advance,
Zdenek