首页 > 解决方案 > CosmosDB:使用现有属性创建新属性的 Gremlin 查询

问题描述

每个顶点都有一个结构:

{
    Id: 123,
    field1: 10
}

我想添加field2到所有顶点,field2使其值等于field1.

挑战在于,我在这里和其他地方发现的几乎所有查询都在 cosmos DB 中给出了语法错误。

例如

g.V().has("field1").property("field2", values("field1")) 

这给出了一个错误:Cannot create ValueField on non-primitive type GraphTraversal

请建议一个 cosmos DB 兼容查询(如果需要,多步)来在 DB 上执行此操作。这是对 DB 的一次性操作,不会再次执行。

标签: graphazure-cosmosdbgremlintinkerpopazure-cosmosdb-gremlinapi

解决方案


As I've mentioned elsewhere, I'm not a CosmosDB expert, but I would venture to guess that what you're asking can't be done with CosmosDB. You definitely have the correct syntax in its most simple form, so the idea that a more complex form would somehow solve the problem seems unlikely. I imagine that property(String, Traversal) is simply unsupported at this time which means that an in-place update isn't not possible.

You could test the complex forms (e.g. select(Traversal,Traversal) for your own satisfaction if you like - for example, from this blog post that demonstrates how to update a vertex from map data:

gremlin> m = [name:'marko',age:29,country:'usa']
==>name=marko
==>age=29
==>country=usa
gremlin> g.withSideEffect('properties',m).
......1>   addV('person').as('vertex').
......2>   sideEffect(select('properties').
......3>              unfold().as('kv').
......4>              select('vertex').
......5>              property(select('kv').by(Column.keys), select('kv').by(Column.values)))
==>v[0]
gremlin> g.V().has('person','name','marko').elementMap()
==>[id:0,label:person,country:usa,name:marko,age:29]

Therefore your only recourse is to query the vertices you wish to update and then send additional traversals back to update the fields you want. Structurally, this suggestion is to simply retrieve the data in a Map form of the vertex identifier for the key and the value holding the data you wish to move and then simply use a for-loop over that returned list of maps to issue a query per id/value:

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> data = g.V().has('age')
==>v[1]
==>v[2]
==>v[4]
==>v[6]
gremlin> data = g.V().has('age').project('id','age').by(id).by('age').toList()
==>[id:1,age:29]
==>[id:2,age:27]
==>[id:4,age:32]
==>[id:6,age:35]
gremlin> data.each { g.V(it['id']).property('personAge',it['age']).iterate() };[]
gremlin> g.V().has('personAge').project('id','age').by(id).by('personAge')
==>[id:1,age:29]
==>[id:2,age:27]
==>[id:4,age:32]
==>[id:6,age:35]

推荐阅读