Is there a Method to find datatypes of schema-less properties of a vertex in OrientDB? - orientdb

Is there a SQL method to find property datatypes for schema-less properties in OrientDB?
There is .type() or .javatype() which can be used against a property in a select query like -
"SELECT Title.type() from #36:1"
This only provides the type for non null properties. Any properties with Null value return no type information.
Also I tried method called 'getPropertyNames' in Javascript function as well (link below).
https://orientdb.com/javadoc/develop/com/orientechnologies/orient/core/record/impl/OVertexDelegate.html#getPropertyNames--
I can use this in a function to pull out all property names but didnt find any similar method to pull PropertyTypes.
var db = orient.getDatabase();
var result = db.command('SELECT FROM V WHERE #rid = '+ id );
var fields = result[0].getRecord().getPropertyNames();
return fields;
Please provide guidance on how to get all property (schema and schema-less) property types for a Vertex record in OrientDB 3.0.
Either SQL method or Javascript Method and its usage will be very helpful.
Appreciate your help.

From the documentation: https://orientdb.com/docs/last/SQL.html#query-the-schema
I think this could help you:
select expand(properties) from (
select expand(classes) from metadata:schema
) where name = 'OUser'
And you could reference to the nummber of type (type column) here:
https://orientdb.com/docs/last/Types.html#supported-types

Related

EF Core completely ignores my selected properties in select

As I understand it, the following code should generate a query containing only the RouteId, RouteNo, and ShipId
var tow = (from t in _context.AllTowData
where t.RouteId == id
orderby t.RouteNo descending
select new TowDefaults {
Id = t.RouteId,
TowNo = t.RouteNo,
ShipId = t.ShipId,
LastTow = t.RouteNo
})
.FirstOrDefault();
However, I get:
SELECT v.route_id, v.route_no, v.tow_id, v.analysis_complete, v.checks_complete, v.cpr_id, v.date_created, v.date_last_modified, v.factor, v.fromportname, v.instrument_data_file, v.instrument_id, v.internal_number, v.mastername, v.message, v.miles_per_division, v.month, v.number_of_samples, v.number_of_samples_analysed_fully, v.prop_setting, v.route_status, v.sampled_mileage, v.serial_no_per_calendar_month, v.ship_speed, v.silk_reading_end, v.silk_reading_start, v.toportname, v.tow_mileage, v.validity, v.year
FROM view_all_tow_data AS v
WHERE v.route_id = '#__id_0'
ORDER BY v.route_no DESC
LIMIT 1
That's every column except the explicitly requested ShipId! What am I doing wrong?
This happens using both a SQL Server and a PostGres database
The property ShipIdis not mapped, either by a [NotMapped] annotation or a mapping instruction. As far as EF is concerned, the property doesn't exist. This has two effects:
EF "notices" that there's an unknown part the final Select and it switches to client-side evaluation (because it's a final Select). Which means: it translates the query before the Select into SQL which doesn't contain the ShipId column, executes it, and materializes full AllTowData entities.
It evaluates the Select client-side and returns the requested TowDefaults objects in which ShipId has its default value, or any value you initialize in C# code, but nothing from the database.
You can verify this by checking _context.AllTowData.Local after the query: it will contain all AllTowData entities that pass the filter.
From your question it's impossible to tell what you should do. Maybe you can map the property to a column in the view. If not, you should remove it from the LINQ query. Using it in LINQ anywhere but in a final Select will cause a runtime exception.

In clause parameters with SPEL

I'm trying to pass multiple In Clause parameters using Spring-El, my query is:
#Query(nativeQuery = true, value = "select a.* from ACC a where (a.iban, a.currency) in (:#{#ibanAccounts.accountNumber} , :#{#ibanAccounts.currency})")
List<ACC> getAccount(#Param("ibanAccounts") List<AccountDetails> ibanAccounts);
But I'm getting following error:
EL1008E:(pos 14): Property or field 'accountNumber' cannot be found on object of type 'java.util.ArrayList$SubList' - maybe not public?
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 14): Property or field 'accountNumber' cannot be found on object of type 'java.util.ArrayList$SubList' - maybe not public?
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:224)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:46)
at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:374)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
In AccountDetails the field is present with public getter.
Can anyone please guide me what's wrong?
I believe what you are looking for is collection projection.
So you need to use something like this
#Query(nativeQuery = true, value = "select a.* from ACC a where (a.iban, a.currency) in :#{#ibanAccounts.![accountNumber]} , :#{#ibanAccounts.currency})")
List<ACC> getAccount(#Param("ibanAccounts") List<AccountDetails> ibanAccounts);

mybatis - Passing multiple parameters on #One annotation

I am trying to access a table in my Secondary DB whose name I am obtaining from my Primary DB. My difficulty is to pass the "DB-Name" as a parameter into my secondary query, (BTW I am using MyBatis annotation based Mappers).
This is my Mapper
#SelectProvider(type = DealerQueryBuilder.class, method = "retrieveDealerListQuery")
#Results({
#Result(property="dealerID", column="frm_dealer_master_id"),
#Result(property="dealerTypeID", column="frm_dealer_type_id", one=#One(select="retrieveDealerTypeDAO")),
#Result(property="dealerName", column="frm_dealer_name")
})
public List<Dealer> retrieveDealerListDAO(#Param("firmDBName") String firmDBName);
#Select("SELECT * from ${firmDBName}.frm_dealer_type where frm_dealer_type_id=#{frm_dealer_type_id}")
#Results({
#Result(property="dealerTypeID", column="frm_dealer_type_id"),
#Result(property="dealerType", column="frm_dealer_type")
})
public DealerType retrieveDealerTypeDAO(#Param("firmDBName") String firmDBName, #Param("frm_dealer_type_id") int frm_dealer_type_id);
The firmDBName I have is obtained from my "Primary DB".
If I omit ${firmDBName} in my second query, the query is trying to access my Primary Database and throws out table "PrimaryDB.frm_dealer_type" not found. So it is basically trying to search for a table named "frm_dealer_type" in my Primary DB.
If I try to re-write the #Result like
#Result(property="dealerTypeID", column="firmDBName=firmDBName, frm_dealer_type_id=frm_dealer_type_id", one=#One(select="retrieveDealerTypeDAO")),
It throws an error that Column"firmDBName" does not exist.
Changing ${firmDBName} to #{firmDBName} also did not help.
I did refer to this blog - here
I want a solution to pass my parameter firmDBName from my primary query into secondary query.
The limitation here is that your column must be returned by the first #SELECT.
If you look at the test case here you will see that parent_xxx values returned by the first Select.
Your DealerQueryBuilder must select firmDBName as a return value and your column must map the name of the return column to that.
Your column definition is always wrong, it should be:
{frm_dealer_type_id=frm_dealer_type_id,firmDBName=firmDBName} or whatever it was returned as from your first select.
Again you can refer to the test case I have above as well as the documentation here http://www.mybatis.org/mybatis-3/sqlmap-xml.html#Nested_Select_for_Association

OrientDB select record count from all graph classes

Any way to get record count for each graph class (V, E and their subclasses)?
I tried to build query in SQL format for current case:
SELECT #class, count(*) FROM V GROUP BY #class
SELECT #class, count(*) FROM E GROUP BY #class
But using count() + GROUP BY is extrimply slow combination.
While console command list classes works fast and return values for count of records in each class (field RECORDS), how to extract this counts via SQL query (or via OrientJS API)?
The main idea is find a way to:
Get list of all classes if database
Get count of records that stored in each class
Technical details
In OrientDB functions you have access to orient variable that have .getDatabase() method. And this method return JAVA ODatabaseDocumentTx class instance. This class provides the method .countClass(className) that returns the number of the records of the class className (method documentation) and it works realy fast.
Solution
Create function in OrientDB Studio with name "getClassCounts", language "javascript", idempotent: true:
var db = orient.getDatabase();
var classesRawInfo = db.getMetadata().getImmutableSchemaSnapshot().getClasses().toArray();
var classesList = {};
var i = classesRawInfo.length;
while(--i) {
var className = classesRawInfo[i].name;
classesList[className] = db.countClass(className);
}
return classesList;
Executing:
via SQL: SELECT getClassCounts()
I think it's not possible, also because it wouldn't so fast as in the console

How to insert a vertex with link type property with the orientjs query builder?

I am trying to insert a vertex with orientjs(previously oriento) query builder. My class has a link type property pointing to another class.
I know I can get it to work with a raw query string but I would love to use the query builder.
Here is what I've tried so far :
db.insert()
.into('VertexClassName')
.set({"prop":"value", "linkProperty":"33:1289287"})
db.insert()
.into('VertexClassName')
.set({"prop":"value", "linkProperty":"#33:1289287"})
I get the following error :
Error on saving record in cluster #13
Am I setting properties in the right way ?
Could the error be related to somtehing else ?
I have sucessfully ran an insert query in the cluster #13 with a raw query string in the studio...
According to the official documentation it seems that the problem might be at the end of your statement
db.insert().into('VertexClassName')
.set({"prop":"value", "linkProperty":"33:1289287"}).one()
.then(function (data) {
// callback
});
Check if your code works adding one() to the pipe line
EDITED: I found this method in orientjs.
db.create('VERTEX', 'V')
.set({
key: 'value',
foo: 'bar'
})
.one()
.then(function (vertex) {
console.log('created vertex', vertex);
});
When using Tinkerpop API they recommend using createVertex instead of insert, because createVertex is intended for graphs and insert for Documents... Could you try with the create() method instead?
I am using SQL and it worked.
sql = "INSERT INTO Station set linked = (select from LinkedClass where LinkedProb = 'value'), prop = 'value'"
OrientVertex vertex = new OrientVertex();
vertex = graph.command(new OCommandSQL(sql)).execute();
I don't think that's possible unless you've added a proper field with the right type 'Link' in your schema. (which I rarely do).
Now instead of having the right 'link' type inserted you can do the opposite, store is as a String, and leverage the query functions to use it correctly:
db.insert().into('table').set({prop: '#15:14'}).one();
And it will be converted as String (which is a bit sad) but then you can use that in your queries:
SELECT eval(prop) FROM table;
And it will be 'eval'-ed to a Node RecordID that you can directly use and call functions like expand() on.
For example:
SELECT name FROM (SELECT expand(eval(prop)) FROM table);
Will eval the node stored in the insert(), grab the node, expand it and collect its name property.