How to overwrite vertices ID in Titan Database? - nosql

I'm using a framework that generates objects Node and they already have assigned a id. Now they need to be converted to Titan vertices with the same ID controlled in the framework (accessed with node.id)
public long addNode(Node node) {
TitanVertex vertex = (TitanVertex) g.addVertex(null);
g.commit();
vertex.setProperty(ID, node.id);
vertex.setProperty(TYPE, node.type);
vertex.setProperty(VERSION, node.version);
vertex.setProperty(TIME, node.time);
vertex.setProperty(DATA, node.data);
...
Error:
java.lang.IllegalArgumentException: Name is reserved: id
But it seems to not allow it. Should I use some fake property to imitate a secondary Id? Does Titan has some way to do that?
Thanks!

Very few graph databases actually allow you to set the element identifier. They all tend to have their own ID systems whether you are using Neo4j, OrientDB, Titan, etc. TinkerGraph is really the only Blueprints implementation that allows ID assignment.
If you want to keep your ID, then you should simply rename it to something else. Instead of "id", perhaps you could use "iid". To make things more transparent, from a programming perspective, you might consider use of the IdGraph wrapper, which would allow you to do something like:
gremlin> base = TitanFactory.open('/tmp/titan-berkley')
==>titangraph[local:/tmp/titan-berkley]
gremlin> g = new IdGraph(base, true, false)
==>idgraph[titangraph[local:/tmp/titan-berkley]]
gremlin> g.addVertex(45)
==>v[45]
gremlin> g.v(45)
==>v[45]
You can see IdGraph allows it to appear as though you are assigning the element id itself. Behind the scenes it is actually just using key indices.

#Stephen, Cant say about the gremlin terminal, but tried this through Titan Java API and it didnt work.
Even after passing id's while creating vertices in the id graph, default id's were assigned to nodes.

Related

Convert Relational Database model to AGE database

I have made an ER diagram of course management system considering Relational Database.
Here is the picture:
[Course Management System] (https://i.stack.imgur.com/RBNfg.png)
How can I map these things in Apache AGE?
What will be the Vertices and what will be the Edges in this case?
I have ER diagram of Course Management System considering Relational Database Model. I want guidance in converting it to Apache AGE Database Model.
I can give you an idea to a certain extent.
Create a Graph with some name(e.g. Registration_Details)
The nodes/vertices will be Person.
Since there are two types of Person, you can use vertex label names to distinguish between them(label name as Student and Teacher and).
Properties of vertex with label name Student will be {'Student_ID': , 'Address': , 'CGPA': } and similarly for vertex with label name Teacher.
Now for Registration details, You'll be creating all possible edges between Student and Teacher. For every edge created you'll be adding properties of edges as well!
example
StudentA(vertex-{StudID: ,...}) ------- edge1({'RegId':123, 'CourseId':789, 'Marks': 80}) ------ TeacherA(Vertex)
I have not included StudentID and TeacherID in edge1 because in Apache AGE the edge already consists of information about the vertexIDs.
Hope this gives some head start for you.
As a rule of thumb, table names in relational databases become label names for vertices, table columns become the properties of those vertices, and the relationships between tables (defined by foreign keys in relational databases) become the edges between vertices.
However, while you could technically map relational databases 1:1 onto graph databases, this may not be the best approach because graphs can offer us more powerful design choices. Check out this blog post for more info:
https://maxdemarzi.com/2015/08/26/modeling-airline-flights-in-neo4j/
You should first write down the relationship between the tables as each table becomes a vertex and it has some properties which are the columns. Then each vertex(TABLE) is connected to another vertex(TABLE) through an edge(RELATIONSHIP). This edge would also have some properties depending upon how you want to utilize the data. You can take help from the here
You need to create a vertex type for each entity (table), and then define the edges that connect the vertices based on the relationships in the ER diagram. You will also need to define attributes for edges along with defining attributes for vertexes as needed.
In your ERD you have defined your tables now you just have to convert those tables into vertexes and the relationships between them would become edges between those vertexes. This means your tables here represent your vertex and your edges represent the relationship between those tables.

How can I persist an HashMap<String, String>?

How do you persist an HashMap in greenDAO and how do you generate the respective entities?
I have read the documentation twice going forward and backward but nothing there.
Google wasn't of any help either.
You should create an Entity with a String-primary-key and a String-proerty for the value:
Entity mapEntity = schema.addEntity("Map");
mapEntity.addStringProperty("key").primaryKey();
mapEntity.addStringProperty("value");
Maybe some other attributes for the properties are needed (depending on your needs) like unique, notNull.
If you want to store your Map inside an entity, that's not quite as simple:
Basically you create an entity like this for storing all Maps:
Entity mapEntity = schema.addEntity("Map");
mapEntity.addLongProperty("id").primaryKey().autoIncrement();
mapEntity.addStringProperty("key").unigue().notNull();
mapEntity.addStringProperty("value");
and then create a relation toOne() or toMany() to reference the corresponding map.
P.S. Maybe you should choose other names than key and value. These variable names are used often and may produce conflicts in greendao.

In Objectify, how do you load an entity by ID without knowing the parent key?

I have an entity group in objectify, typical SomeParentClass and SomeChildClass. I want to do something like this to load an instance of SomeChildClass from the datastore.
ofy().load.type(SomeChildClass.class).id(idOfSomeChildClassInstace);
This is returning nothing found. Seems that you need to know the parent of SomeChildClass to get it from the datestore. This I know works.
Key<SomeChildClass> k = Key.create(someParentClass.generateKey(), SomeChildClass.class, idOfSomeChildClassInstace);
ofy().load().key(k).now;
What if I want to load an instance of SomeChildClass without knowing the parent, by just having the id of SomeChildClass.
You cannot do that - the actual full identifier of an entity is the kind and id of each of its ancestors as well as it's own kind and id. That is why building the full key works, but using just the child entity id does not. Another way of looking at it that ids are only unique between siblings of the same parent.
The easiest way to solve your issue is to produce a key for your child entity, then get the 'web safe string' for it. This string contains all the information of the entity and all it's parents and can be used to fully reconstitute the full id.
Using objectify:
String websafeKey = Key.create(parentKey, Entity.class, id).getString();
Key<Entity> key = Key.create(websafeKey);
You can also do this with the low level api if you need to.
You need to know the whole Key to be able to get() an entity. A child key consists of: kind, ID and parent key. So you need to provide all three.

Entity Framework 4.1: HOWTO know the next identifier assigned by Database automatically

I have POCO objects which their identifiers are unique and generated automatically by the database, so the problem is when you want to know for some reason which will be the next identifier that the database is going to assign to the next record you are inserting. As far as I know it is only possible after performin dbContext.SaveChanges() so I would like to know if I am right or is there a way to know the next identifier assigned by database automatically.
is there a way to know the next identifier assigned by database
automatically
Well, the next one NO. And if your code depends on it, you really need to change your design.
If you need the identifier to insert related objects, you should check some other questions because you can assign entities to eachother instead of ID's and it will be fine.
I agree with the general purport of the comments that having to know an identity value is "smelly". But on the other hand sometimes you have to live with a given design.
You can't really get the value of the next id, but you can get the value of the assigned id in time by using a TransactionScope.
using (var trans = new TransactionScope())
{
// Create new object
...
context.SaveChanges();
int id = newEntity.Id;
dependentEntity.IdString = string.Format("{0:0000000}", id);
context.SaveChanges();
trans.Complete();
}

how to create a auto-incremented attribute in xcode managed object model

Hey, what i want to do is to make a int that will be the ID of the entity and auto increment itself whenever a new entity is added (just like a SQL identity property). Is this possible? i tried using indexed (checked on attribute) however there is no description to what indexed even does.
EDIT:
I am adding annotations to a map, when you click the pin the annotationview with a chevron shows up. Now when you click this button i would like to load an associated picture. However the only way i know how to link the picture to this button is to give the picture a unique id, and then set the button.tag to this id and then load based on the button.tag.
This kind of concept is contrary to the principles of Core Data - the idea is that you're managing sets of entities with properties, not rows in a database or other things that need to be uniqued. (If you're using the SQLite store, Core Data will create an ID for you behind the scenes, but you can't access it.)
You should probably reconsider (or at least give more details about) the problem you're trying to solve, because as it stands, Core Data will not let you autoincrement a variable.
If you absolutely must, you can manually increment on insert by having some NSNumber ID field on your entity, then every time you insert a new entity, get the existing entities sorted by that ID and limited to one result (using a NSFetchRequest with various options), grab that entity's ID, add one, and set it as the new entity's ID. It's a lot of work, though, and probably error-prone.
Edit: Based on the extra information, I'd say rather than trying to autoincrement an ID yourself, find some other guaranteed-unique property of the annotation and either use that directly or write a hash function that uses it to generate your unique ID. For example, use the latitude & longitude to build a single integer that uniquely represents that point within your system. Other than that, there's no way around having to increment the ID yourself.
I agree that this is a sticky problem - I haven't ever come across something like this in Core Data before, and I can see where autoincrementing might be useful :)
This is the simplest way, but takes some effort.
Create an "index" attribute in your Entity. Make it a String
When you create a new one, generate a GUID using CFUUIDCreate() and CFUUIDCreateString()
Assign the GUID to the "index" attribute
Voila, you now have a nearly-perfect unique ID, ready to use for caching locally and using as needed
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef uuidStringRef = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);
NSString* guidString = [NSString stringWithString:(__bridge NSString*)uuidStringRef];