Pyorient : Create an edge in OrientDB without using raw query - orientdb

I tried
graph.create_edge(Friend, orientRecord1, orientRecord2)
But I get AttributeError: 'OrientRecord' object has no attribute '_id'
because orientRecord does not have an _id in it. What am I doing wrong? How can I use this function?
Here are my class structures
class Person(Node):
id = String(unique = True)
name = String()
pass
class Friend(Relationship):
pass

You can create an edge with the "command" statement:
and the result is this:
That is correct output, since the graph is this :

Related

NHibernate error system.object[] when retrieving multiple entities in one query

I have a HQL query like this:
string QueryString = select client, transporter
from BaseClient as client, BaseTrans as transporter
where client.tr = transporter.Id and transporter.badge = 1
order by transporter.date;
But when I use this hql I receive the following error :
The value "System.Object[]" is not of type "xxx" and cannot be used in this generic collection.
Parameter name: value
Just like Example but, when I omit the Transporter entity in my select it works.
Like :
string QueryString = select client
from BaseClient as client, BaseTrans as transporter
where client.tr = transporter.Id and transporter.badge = 1
order by transporter.date;
But I need transporter in my select, because I use order by.
By the way, I have 2 hbm Client.hbm.xml and Transporter.hbm.xml. Each hbm have their own Class and Table.
i call it with :
IQuery requete = this.CreateQuery(QueryString);
IList<Client> executions = requete.List<Client>();
it hang on this line, when hibernate try to convert to the list
This happens because your result-set will likely be a multi-dimensional array where the first column represents a Client and the 2nd column contains a Transporter.
What happens if you change your code like this:
IQuery requete = this.CreateQuery(QueryString);
var result = requete.List();
var clients = result[0] as IEnumerable<Client>;
(I have no NHibernate installed on this system so I cannot just test something out quickly without creating and setting up a new project. :)

OrientDB Nested JSON Insert

I have a OrientDB question. For the statement
INSERT INTO Account CONTENT
{ name : 'Luca',
vehicles : {
#class : 'Vehicle',
type : 'Car',
model : 'Maserati',
isItTrue: false
}
}
I get a result (see screenshot), but the class/table 'Vehicle' does not contain any entries. Is this a valid result?
I expected that automatically some values are written into 'Vehicle' and connected to 'Account'. Only the column 'vehicles' from 'Account' contains JSON-Data.
Thank you for your response.
Best regards
Karo
Screenshot OrientDB
With your query you are inserting embedded data into Account, if you want to insert some data into Account and Vehicle, you should do it in different queries and then if you want you can connect them with an edge. See example:
create class Account extends v
create class Vehicle extends v
create class owns extends e
create property Account.name String
create property Vehicle.type String
create property Vehicle.model String
create property Vehicle.isItTrue BOOLEAN
insert into Account(name) values ("Luca")
insert into Vehicle(type, model, isItTrue) values ("Car", "Maserati", false)
create edge owns from (select from Account where name = "Luca") to (select from Vehicle where model = "Maserati")
Alternatively, if you are not looking to create edges and you just want a link from document to document, the below will give you desired results in single insert / transaction while still keeping your json structure for the linked record
create class Account
create class Vehicle
create property Account.vehicles embedded Vehicle
INSERT INTO Account set name = "luca", vehicles = [ {
"#type": "d",
"#class" : "Vehicle",
"type" : "Car",
"model" : "Maserati",
"isItTrue": false
}]

What is the correct way to UPDATE a document in an embedded list?

I am having some trouble finding a way to update, i.e. modify or delete a certain document in an embedded list. Here is my case:
CREATE CLASS Tag EXTENDS V
CREATE PROPERTY Tag.label STRING
CREATE CLASS Profession
CREATE PROPERTY Profession.jobtitle STRING
CREATE PROPERTY Profession.tags LINKSET Tag
CREATE CLASS UserProfile EXTENDS V
CREATE PROPERTY UserProfile.screenname STRING
CREATE PROPERTY UserProfile.profession EMBEDDEDLIST Profession
So, adding an entry to UserProfile.profession is no problem:
UPDATE UserProfile ADD profession =
{"#type":"d","#class":"Profession","jobtitle":"Actress", "tags" : ["#22:5"]}
WHERE screenname = 'emma'
Given some entry 'emma' for UserProfile and a Tag with id #22:5.
However, when I try to update the Profession-document with jobtitle 'Actress', how exactly should I proceed? I tried the following approach, which worked with but one entry in the list only:
UPDATE UserProfile SET profession =
{"#type":"d","#class":"Profession","jobtitle":"Actress", "tags" : ["#22:7", "#22:9"]}
WHERE profession.jobtitle = 'Actress'
AND screenname = 'emma'
This statement throws no exception and returns 0 as number of affected records.
In general: How do I access a specific entry (using a key of the document itself) in an embedded list or set to update or remove it?
Also: is there an easier way to update the tags linkset in the Profession-document in the embedded list? Or do I always have to get the whole document and write a modified version back?
Thanks!
Ingo
You can use
UPDATE UserProfile set profession = [{"#type":"d","#class":"Profession","jobtitle":"Actress", "tags" : ["#22:7", "#22:9"]}]
WHERE profession.jobtitle contains "Actress" AND screenname = 'emma'
UPDATE
You could use this javascript function
var g=orient.getGraph();
var b=g.command("sql","select from userprofile");
var tag1=g.command("sql","select from #22:7");
var tag2=g.command("sql","select from #22:9");
for(i=0;i<b.length;i++){
var screenname= b[i].getProperty("screenname");
if(screenname=="emma"){
var pro=b[i].getProperty("profession");
for(j=0;j<pro.length;j++){
if(pro[j].field("jobtitle")=="Actress"){
pro[j].field("tags",[tag1[0],tag2[0]]);
}
}
b[i].save();
}
}
try this
UPDATE UserProfile SET profession.jobtitle = 'aaaa'
WHERE profession.jobtitle = 'Actress'
AND screenname = 'emma'

Vertx : insert array of objects into my database without without for loop

I have an array of json object which i want to insert into my database, and instead of using a loop 'for' I'd like to use stored procedure, my question is how to do it without using the add method of jsonArray because as i see it takes one by one my records.
For example I have an array like this : [{'website': 'stackoverflow', 'description': 'very useful'}, {'website' : 'google', 'description' : 'huge informations'}] and I don't want to use it like this :
for(i=0;i<ja.size();i++){
JsonArray params = new JsonArray();
params.add('website',ja.getJsonObject(i).getValue("website")).add('website',ja.getJsonObject(i).getValue("description"));
}
Regards.

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.