Add Additional Property to Neptune DB - graph

I am trying to add additional property called "insert_date" to the existing vertices and edges. I tried
g.V().setProperty('insert_date',datetime('2020-10-06'))
Error:
{
"requestId": "33cf8df5-3cbe-41ac-b650-5752debec04d",
"code": "MalformedQueryException",
"detailedMessage": "Query parsing failed at line 1, character position at 10, error message : token recognition error at: 'rop'"
}
I am trying the above command from Neptune Notebook.
It just adds new vertices with insert_date property. But I did not find the way to alter existing vertices or edges.
Please suggest if this is possible. As I want to implement delta extraction so that I can extract only new vertices or edges every time I run ETL.
Thanks

To add a property to an existing vertex in Gremlin you use the property() step. For example, if you wanted to add a property insert_date to a vertex with the id of A you would use the following statement:
g.V('A').property('insert_date', '2020-10-06')
The property() step will add or update the specified property to the new value. This will occur for all the current elements being passed in. For example, if you only wanted to update the elements that did not have an insert_date property you could do this via:
g.V().hasNot('insert_date').property('insert_date', '2020-10-06')
In each of these example the property will be added as part of an array of values. If you want to set the property to only contain a single value then you can use the property() step overload that takes the cardinality like this:
g.V('A').property(Cardinality.single, 'insert_date', '2020-10-06')
One thing to note in the code you have listed above. While Neptune does support the datetime() function for string-based queries, if you are not using a GLV then you will need to create this value and pass in a Native Date/Time as described here.

Below Command worked to add additional properties to existing Graph.
g.V().property("insert_date","2020-01-01 00:00:00")

Related

Gremlin: property name with static and dynamic

I'm trying create a property of vertice with static and dynamic value using selected properties. Here the code:
g.V('%s').as('source')
.until(or(hasLabel('target').has('v', '1'),loops().is(10)))
.repeat(__.in())
.outE('e').as('edge')
.inV().as('u')
.select('source')
.property(single, 'v', '1')
.property(single, union(constant('p_'),select('u').id()), select('e').properties('r').value())
This query is to copy property of edges as value and id of vertice as name of property with prefix 'p_'. The copy works, but the property name does not works, it's saving just prefix 'p_'.
Any ideas about this behaviour? I'm using tinkerpop 3.4.3, same the Neptune version.
Thanks!
The union() step in this traversal will not return a concatenation of the prefix and the property as you are hoping. Instead, it will return a single traverser for each item in the union(). In this case one containing "p_", one containing the id(), and one containing the "r" property.
Unfortunately, Gremlin does not have a string concatenation function that will accomplish this for you. See this below:
Concatenate Gremlin GraphTraversal result with string
As you are using Neptune the proposed solution in that answer will not work either as Neptune does not support lambdas in a traversal. Unfortunately, in this scenario the best way to accomplish this is likely to return the data to your application, concatenate the strings, and then update the property.

Upsert properties using Gremlin

I'm using python and AWS Neptune.
I'm using the "upsert" pattern by id:
g.V().has(node_type,'id',node.id).fold()
.coalesce(__.unfold(),__.addV('node_type').property('id',node.id)).
property('property','first').next()
Indeed the the vertex is added (Or selected from the graph) with the added property.
Now I want to add two more properties which I fail to add:
I want to add "max" property. If the vertex has the property, I want to take the max value of it and the value "10" (for example). Tried to add the following statement to my query but it doesn't work:
property('time_max', __.max(__.values('max'), 10))
But I'm getting an exception the "Could not locate method: DefaultGraphTraversal.max"
Another property that Increments "count" property the same way. I got the same exception on the "sack" method.
How can these properties can be added? Is the only way is to get the vertex and then commit it? I want it to be as efficient as possible.
Thanks!
The max() step is used to find the maximum value in a stream or collection such as in this simple example:
gremlin> g.inject(1,2,3).max()
==>3
You could do something like this instead
union(values('max'),constant(10)).max()

Gremlin code to find 1 vertex with specific property

I want to return a node where the node has a property as a specific uuid and I just want to return one of them (there could be several matches).
g.V().where('application_uuid', eq(application_uuid).next()
Would the above query return all the nodes? How do I just return 1?
I also want to get the property map of this node. How would I do this?
You would just do:
g.V().has('application_uuid', application_uuid).next()
but even better would be the signature that includes the vertex label (if you can):
g.V().has('vlabel', 'application_uuid', application_uuid).next()
Perhaps going a bit further if you explicitly need just one you could:
g.V().has('vlabel', 'application_uuid', application_uuid).limit(1).next()
so that both the graph provider and/or Gremlin Server know your intent is to only next() back one result. In that way, you may save some extra network traffic/processing.
This is a very basic query. You should read more about gremlin. I can suggest Practical Gremlin book.
As for your query, you can use has to filter by property, and limit to get specific number of results:
g.V().has('application_uuid', application_uuid).limit(1).next()
Running your query without the limit will also return a single result since the query result is an iterator. Using toList() will return all results in an array.

Janusgraph/TinkerPop - Constraint violation - How to add or update an existing Vertex

I have defined in my schema constraints to ensure uniqueness of given vertices based one or more properties. For example:
mgmt.buildIndex('byTenandIdUnique',Vertex.class).addKey(tenantId).unique().buildCompositeIndex()
As expected now, when I try to add a Vertex that already exists, I am getting an error like below:
aiogremlin.exception.GremlinServerError: 500: Adding this property for key [tenantId] and value [ACME2_AX2] violates a uniqueness constraint [byTenandIdUnique]
I am writing a Python application to load log files, with Goblin OGM, so it is expected that the data will repeat, and I don't want multiple instances of the same Vertex, hence the constraint.
Is there a way in TinkerPop or JanusGraph to update a Vertex in case it already exists instead of throwing this exception? Or is this something that the OGM should handle or maybe the code itself by querying the graph before any transaction?
TinkerPop does not do anything to enforce a schema, so the schema restriction here is specific to JanusGraph. The behavior is as you described: if you have a unique index defined and then attempt to add another element that conflicts with an existing element, an exception is thrown.
From a JanusGraph perspective, your logic will need to account for this properly. The code below is based on a common recipe using the coalesce() step that you can read more about here.
// check for existence of a vertex with the tenantId property
// if the vertex exists, return that vertex
// else create a new vertex with the tenantId
v = g.V().property("tenantId", "ACME2_AX2").fold(). \
coalesce( __.unfold(), __.addV().property("tenantId", "ACME2_AX2") ). \
next();
I don't use Goblin, so I'm not aware of whether Goblin is capable of handling this or whether it passes that responsibility on to the app developer, but checking for existence before setting the property is still an appropriate way to handle the situation.

EMC Documentum DQL - How to delete repeating attribute

I have a few objects created on my database and I need to delete some of the repeating attributes related to them.
The query I'm trying to run is:
UPDATE gemp1_product objects REMOVE ingredients[1] WHERE (r_object_id = '08015abd8002cd68')
But all I get is the folloing error message:
Error querying databse.
[DM_QUERY_E_UPDATE_INDEX]error: "UPDATE: Unable to REMOVE tghe attribute ingredients at index 1."
[DM_OBJECT_W_DELETE_ATTR_POSITION_ERROR]warning: "attempt to delete
non-existent attribute 88"
Object 08015abd8002cd68 exists and I can see it on the database. Queries like SELECT and DELETE work fine but I do not want to delete the whole object.
There is no easy way to do this. The reason is that repeating attributes are ordered, to enable multiple repeating attributes to be synchronized for a given object.
Either
set the attribute value to be empty for the given position, and change your code to discard empty attributes, or
use multiple DQL statements to shuffle the order so that the last one becomes empty, or
change your data model, e.g. use a single attribute as a property bag with pre-defined delimiters.
Details (1)
UPDATE gemp1_product OBJECTS SET ingredients[1] = '' WHERE ...
Details (2)
For each index; first find the value of index+1:
SELECT ingredients
FROM gemp1_product
WHERE (i_position*-1)-1 = <index+1>
ENABLE (ROW_BASED)
Use the value in a new query:
UPDATE gemp1_product OBJECTS SET ingredients[1] = '<value_from_above>' WHERE ...
It should also be possible to do this by nesting DQL somehow, but it might not be worth the effort.
Something is either wrong with your query or with your repository. I think you are mistyping your attribute name or using wrong index in your UPDATE query.
If you google for DM_OBJECT_W_DELETE_ATTR_POSITION_ERROR you'll see on this link a bit more detailed explanation:
CAUSE: Program executed a DeleteAttr operation that specified an non-existent attribute position (either a negative number or a number larger than the number of attributes in the object).
From this you could guess that type isn't in consistent state, or that you are trying to remove too big index of your repeating attribute, etc. Did you checked your repository with Consistency checker Job and other similar Jobs?
As of for the removing of repeating property (sttribute) value with DQL query, this is unachievable with single query since you need to specify index position which you don't know at first. But writing a simple script or doing it manually if it's not big amount of values to delete is the way you want to go.

Resources