Identifying if 2 Vertices are connected with edge using Orientdb 3 and tinkerpop 3 - orientdb

I have been trying to look through documentation. I am just trying to find a simple example to identify as mentioned in the title if 2 vertices are connected to each other. This is for OrientDB 3 using the tinkerpop API blueprints 2.6.
Ex:
Vertex v1;
Vertex v2;
boolean connected = false;
connected = <somefunction returns true/false if v1 and v2 connected by an edge>;
Can someone please provide an example if they have seen something like this?

try this:
String db_name = "dbname";
String path = "remote:localhost/" + db_name;
OrientDB orientDB = new OrientDB("remote:localhost", "username", "password", OrientDBConfig.defaultConfig());
try(ODatabaseSession db = orientDB.open(db_name,"username","password"))
{
ORID theEdge = new ORecordId("edge_rid");
OEdge e = db.load(theEdge);
ORID theVertex = new ORecordId("v1_rid");
OVertex v1 = db.load(theVertex);
ORID theVertex2 = new ORecordId("v2_rid");
OVertex v2 = db.load(theVertex2);
boolean connected = false;
OVertex from = e.getFrom();
OVertex to = e.getTo();
if(from.getIdentity().equals(v1) && to.getIdentity().equals(v2))
{
connected = true;
}
if(connected)
{
System.out.println("Vertex v1: " + from.getIdentity());
System.out.println("Vertex v2: " + to.getIdentity());
}
}
Hope it helps
Regards

You need iterate one vertex(v1) edges and check if it s connecting to the other vertex(v2):
OrientVertex v1,v2;
for (Edge e : (Iterable<Edge>)() -> v1.edges(Direction.OUT))
if (e.vertices(Direction.IN).next().id().equals(v2.id())) {
}

Related

OrientDB inconsistent vertex persist after remove edge with MMAPI

Consider this code:
private void testMMAPIinLab() {
OrientDB orientDB = new OrientDB("remote:localhost",OrientDBConfig.defaultConfig());
OrientDBConfigBuilder poolCfg = OrientDBConfig.builder();
poolCfg.addConfig(OGlobalConfiguration.DB_POOL_MIN, 5);
poolCfg.addConfig(OGlobalConfiguration.DB_POOL_MAX, 10);
//poolCfg.addConfig(OGlobalConfiguration.RID_BAG_EMBEDDED_TO_SBTREEBONSAI_THRESHOLD, -1);
ODatabasePool dbPool = new ODatabasePool(orientDB,"lab", "root", "toor", poolCfg.build());
ODatabaseSession db = dbPool.acquire();
db.begin();
System.out.println("creando el vértice....");
OVertex v1 = db.newVertex();
v1.save();
System.out.println("save rid: "+v1.getIdentity().toString());
OVertex v2 = db.newVertex();
v2.save();
System.out.println("v2 save rid: "+v2.getIdentity().toString());
System.out.println("crear un edge.");
OEdge oe = v1.addEdge(v2);
v1.save();
System.out.println("llamando a commit...");
db.commit();
db.close();
System.out.println("configuración grabada:");
System.out.println("v1: "+v1.getIdentity().toString());
System.out.println("v2: "+v2.getIdentity().toString());
System.out.println("edge: "+oe.getFrom()+" --> "+oe.getTo());
// abrir otra transacción
db = dbPool.acquire();
db.begin();
System.out.println("crear v3");
OVertex v3 = db.newVertex();
v3.save();
System.out.println("v3 save rid: "+v3.getIdentity().toString());
System.out.println("modificar v1...");
v1.setProperty("value", "test");
System.out.println("borrar relación con v2");
// borrar el edge anterior
Iterator<OEdge> toRemove = v1.getEdges(ODirection.OUT).iterator();
while (toRemove.hasNext()) {
OEdge removeEdge = toRemove.next();
//removeEdge = (OEdge) edge;
removeEdge.delete();
removeEdge.save();
}
System.out.println("agregar una relación de v1 a v3");
OEdge oe2 = v1.addEdge(v3);
v1.save();
// crera en edge nuevo a v3
db.commit();
System.out.println("v1 edges: "+v1.getEdges(ODirection.OUT));
System.out.println("v3 post-commit rid: "+v3.getIdentity().toString());
System.out.println("oe2: "+oe2.getFrom()+" --> "+oe2.getTo());
db.close();
}
When you run it you get V1 with two out edges. One with the EdgeRID of the removed edge and one that point to V3.
I you clic over the removed edge it show {} and report a 404 error. The vertex are persisted so the error is inside the database.
The error is in the while that remove the edges. If you use the edge reference it work, but in the real code I do not know how many edges the vertex have.
V2 and V3 have the correct IN references.
How could I fix this?
This depends on the fact that vertices are shared between different database sessions.
An easy fix consists in reloading the vertices by ID before using them in the second session:
// abrir otra transacción
db = dbPool.acquire();
db.begin();
//RELOAD THE VERTEX BEFORE USING IT AGAIN!
v1 = db.load(v1.getIdentity());

creating edges by "joining" 2 classes

In Orientdb 3.0 RC1 (Tinkerpop/Gremlin community edition) I have 2 vertex classes:
- 'Company' with 1 property 'address'
- 'Address' with 1 property 'address' having a UNIQUE_HASH_INDEX on this property
Need to create edges of class 'Location' between 'Company' vertexes to the corresponding 'Address' vertex based on having the same 'address' property value.
First I tried using Gremlin the following way:
g.V().hasLabel("Company").as("a").
V().hasLabel("Address").as("b").
where("a", eq("b")).by("address").
addE("Location").next()
But the mid-traversal is not hitting the index .....I guess the OrientDB-Gremlin implementation not complete yet or my above query not good.
Then I converted the above to use a sideEffect():
g.V().hasLabel("Company").sideEffect{g.V().hasLabel("Address").has("address",it.get().property('address').value()).addE('Location').from(it.get()).next()}
but after quickly adding around 1k edges the query abruptly aborts and the OrientDB logs a lot of warnings like this:
"WARNI {db=ter1050} This database instance has 1280 open command/query result sets, please make sure you close them with OResultSet.close()"
So once again .....my query has a problem or I hit a bug.
I didn't find a way to do it in OrientDB SQL also.
I know this can be done using Tinkerpop API in Java but I was hoping for something more simple.
Try this:
OrientDB orientDB = new OrientDB("remote:localhost/", "<username>", "<password>", OrientDBConfig.defaultConfig());
ODatabaseDocument db = orientDB.open("<db name>","<username>", "<password>");
OResultSet result = db.command("select from Company");
OResultSet address_class = db.command("select from Address");
List<OResult> company = new ArrayList<OResult>();
List<OResult> address = new ArrayList<OResult>();
while(result.hasNext())
{
OResult record = result.next();
company.add(record);
}
while(address_class.hasNext())
{
OResult record = address_class.next();
address.add(record);
}
for(int i = 0; i < company.size(); i++)
{
String company_address = company.get(i).getProperty("address");
for(int j = 0; j < address.size(); j++)
{
String addresses = address.get(j).getProperty("address");
if(company_address.equals(addresses))
{
ORecordId company_rid = company.get(i).getProperty("#rid");
ORecordId addresses_rid = address.get(j).getProperty("#rid");
db.command("create edge Location from " + company_rid + " to " + addresses_rid);
}
}
}
db.close();
orientDB.close()
this is the result:
Hope it helps
Regards

Auto increment Vertex property in orientdb

I am using Orientdb 2.2.12.
I want to set an auto-increment property to vertex
e.g
for(i 1 to 100)
{
vertex.setProperty("counter", AUTO_INCREMENT_Value(start = 0))
}
I tried to achieve this by creating sequence
sequenceLibrary.createSequence(AUTO_INCREMENT_Value, SEQUENCE_TYPE.ORDERED, new OSequence.CreateParams().setStart((long) 0));
for(int i=1 ; i<=100; i++)
{
vertex.setProperty("counter", AUTO_INCREMENT_Value);
graph.commit();
graph.shutdown();
}
Though it work fine in single threaded system but in multithreaded system it gave ambiguous results.
I gave each thread a seperate OrientGraph instance from OrientGraphfactory as stated in official doc :
OrientGraphFactory graphFactory = new OrientGraphFactory(
"remote:" + IP + ":" + PORT+ "/" + appName).setPool(1, 100);
OrientGraph graph = graphFactory.getTx();
Is there any way to achieve this in orientdb.
Thanks..!

OrientDB fails to persist a Vertex, returns ORID but with null vertex eg v(null)[#3:4]

I cant get OrientDB to persist an OrientVertex or an oDocument using the java API.
although its works when I use SQL and the OCommand.
trying to persist a vertex with foll code
val factory: OrientGraphFactory = new OrientGraphFactory("plocal:localhost/database", "admin", "admin");
val graph = factory.getTx
val oDocument: ODocument = UserEntityMapper.toODocument(user)
println("ODocument = = "+ oDocument)
val orientVertex = new OrientVertex(graph, oDocument)
println("BEFORE orientVertex = "+ orientVertex)
graph.commit()
println("AFTER orientVertex = "+ orientVertex)
I get debug printouts as
ODocument = {phoneNumber:45435345,email:moses#email.com,dateOfBirth:-766198800000,lastName:Johnson,firstName:Moses,avatarURL:null,loginInfo:{providerID:credentials,providerKey:moses#email.com},userID:a8d96be9-1d09-4e8f-bf8d-6a0d32e1e5aa}
BEFORE orientVertex = v(null)[#3:-2]
AFTER orientVertex = v(null)[#3:4]
As you can see, the vertex is null. Nothing is persisted. I get an ORID that changes the cluster position number.
When I repeat the save the cluster position number is incremented
BEFORE orientVertex = v(null)[#3:-3]
AFTER orientVertex = v(null)[#3:7]
Why does this happen and how can I fix this please? There are no exceptions so i cant tell whats wrong. The cluster/table for User exists on the DB with all teh right fields.
I am using orientdb-community-2.2.0 and Scala.
regards
Sorted it out at last. I was instantiating the ODocument without the class name. In
UserEntityMapper.toODocument(user)
I was doing the equivalent of this
new ODocument(Map("name"->"john", "city" -> "London"))
instead of this
new ODocument("User").fromMap(Map("name"->"john", "city" -> "London"))
So the DB did not pick up the User class.
Thanks actual for pointing me in the right direction

How to create an ArcMap Layer from a ArcGIS Map Service

I would like to add an ILayer created from an ArcGIS Server Map service to an IMap with ArcObjects, but don't see how to do it.
I am getting an IMapServer3 with the following code, where mapName = the map service:
serverContext = som.CreateServerContext(mapName, "MapServer");
IServerObject serverObject = serverContext.ServerObject;
IMapServer3 mapServer = (IMapServer3)serverObject;
It looks like I can get an ILayer from an IMapServerGroupLayer, but it looks like the IMapServerGroupLayer is looking for a different connection type than I am using.
If you have an example of getting an ILayer from a Map Service, your assistance is appreciated.
This is what worked...
private static void GetLayerFromMapServerLayer()
{
IAGSServerConnectionName servConnName = new AGSServerConnectionNameClass();
IPropertySet props = new PropertySetClass();
props.SetProperty("machine", "server");
servConnName.ConnectionProperties = props;
IAGSServerConnectionFactory pAGSServerConnectionFactory = new AGSServerConnectionFactoryClass();
IAGSServerConnection pAGSConnection = pAGSServerConnectionFactory.Open(props, 0);
IAGSEnumServerObjectName pEnumSOName = pAGSConnection.ServerObjectNames;
IAGSServerObjectName pSOName = pEnumSOName.Next();
while (pSOName != null)
{
if (pSOName.Name == "Base_Map")
break;
pSOName = pEnumSOName.Next();
}
IName pName = (IName)pSOName;
IMapServer mapServer = (IMapServer)pName.Open();
IMapServerLayer msLyr = new MapServerLayerClass();
msLyr.ServerConnect(pSOName, mapServer.DefaultMapName);
IMapServerGroupLayer group = (IMapServerGroupLayer)msLyr;
ILayer msLayer = (ILayer)msLyr;
//return msLayer;
MapDocument mapDoc = new MapDocumentClass();
mapDoc.Open(#"F:\~mkoneya~2011_82_13_58_30.mxd");
IMap myMap = mapDoc.get_Map(0);
myMap.AddLayer(msLayer);
mapDoc.Save();
}