gremlin - 在 Gremlin 中,仅当版本属性与数字匹配时,如何修改顶点的属性?
问题描述
在 Gremlin/Tinkerpop 中,我想在 Vertex 上执行版本化 upsert。如果有一个现有的顶点,我只想在版本与版本号属性匹配时对其进行变异。
下面是尝试使用gremlinjs
. 它无法创建顶点,以后的查询无法找到它。
(以前的版本有一个编译错误,但这是一个 javscriptism 未记录的语法问题)
[更新] 请参阅有关问题的答案的评论。https://gist.github.com/pszabop/3b07fa7caadf1dbd86953a713ed96ce0的工作版本
//
// o.id o.__version, and o.__lastUpdate have special meaning or are reserved
//
graphdb.upsertVertexVersioned = async function(type, o) {
const g = traversal().withRemote(this.connection);
let oldVersion;
if (!o.id) {
o.id = uuidv4();
}
if (!o.__version) {
o.__version = 0;
oldVersion = 0;
} else {
oldVersion = o.__version;
o.__version++;
}
o.__lastUpdate = Date.now();
// @see http://tinkerpop.apache.org/docs/current/recipes/#element-existence
// The pattern we are using is keys get copied into properties that can be used
// by the graph database for its work, and then the
// entire object is JSON serialized into a generic `obj` property.
// XXX TBD use graphson?
const v1 = await g.V().has(type, 'id', o.id)
.fold()
.coalesce(__.unfold(),
__.addV(type).property('id', o.id)
.property('version', o.__version)
).choose(__.values('version').is(oldVersion),
__.in_()
.property('lastUpdate', o.__lastUpdate) // updated properties go here
.property('version', o.__version) // updated properties go here
.property('obj', JSON.stringify(o)), // updated properties go here
__.out()
).next();
return o;
};
参考:
版本
- janusgraph/janusgraph:最新
- gremlinjs 3.4.4
解决方案
我使用“现代”玩具图尝试了您的代码的变体,事实证明您的代码对我来说是正确的。我相信以下内容抓住了您所做工作的精神:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().property('version',1).iterate()
gremlin> name = 'marko'
==>marko
gremlin> oldVersion = 1
==>1
gremlin> version = 2
==>2
gremlin> g.V().has('person','name',name).
......1> fold().
......2> coalesce(unfold(),
......3> addV('person').property('name',name).property('version',version)).
......4> choose(values('version').is(oldVersion),
......5> property('version', version).constant('edited'),
......6> constant('same'))
==>edited
gremlin> g.V().has('person','name',name).
......1> fold().
......2> coalesce(unfold(),
......3> addV('person').property('name',name).property('version',version)).
......4> choose(values('version').is(oldVersion),
......5> property('version', version).constant('edited'),
......6> constant('same'))
==>same
gremlin> name = 'stephen'
==>stephen
gremlin> g.V().has('person','name',name).
......1> fold().
......2> coalesce(unfold(),
......3> addV('person').property('name',name).property('version',version)).
......4> choose(values('version').is(oldVersion),
......5> property('version', version).constant('edited'),
......6> constant('same'))
==>same
gremlin> g.V().has('person','name',name).
......1> fold().
......2> coalesce(unfold(),
......3> addV('person').property('name',name).property('version',version)).
......4> choose(values('version').is(oldVersion),
......5> property('version', version).constant('edited'),
......6> constant('same'))
==>same
gremlin> oldVersion = 2
==>2
gremlin> version = 3
==>3
gremlin>
gremlin> g.V().has('person','name',name).
......1> fold().
......2> coalesce(unfold(),
......3> addV('person').property('name',name).property('version',version)).
......4> choose(values('version').is(oldVersion),
......5> property('version', version).constant('edited'),
......6> constant('same'))
==>edited
gremlin> g.V().has('person','name',name).
......1> fold().
......2> coalesce(unfold(),
......3> addV('person').property('name',name).property('version',version)).
......4> choose(values('version').is(oldVersion),
......5> property('version', version).constant('edited'),
......6> constant('same'))
==>same
gremlin> g.V().has('person','name','stephen').elementMap()
==>[id:19,label:person,name:stephen,version:3]
鉴于您对问题的描述,我建议您尝试简化一下。你说的问题是:
它无法创建顶点,以后的查询无法找到它。
choose()
如果您删除逻辑,它是否可以正常工作?换句话说,你能让基本的 upsert 操作工作吗?如果不是,那么问题似乎与查询的那部分无关,尽管您所拥有的似乎遵循推荐的做法,所以我不确定可能有什么问题。
推荐阅读
- javascript - Promise `.then`、`.catch` 和 `.finally` 如何以及何时进入 EventLoop 微任务队列?
- google-apps-script - 基于标题名称而不是列位置谷歌表过滤
- git - 如果我使用 https 连接到存储库,如何使用 SSH 密钥?
- vue.js - 在 Vue 中使用 Stripe 时如何应用自定义字体?vue-stripe-elements-plus
- sql - 如何在 SQL 中计算使用 CASE 而没有子查询创建的类别的出现次数?
- amazon-s3 - aws python aws中boto和boto3的区别,与S3相关
- javascript - window.matchMedia Javascript 在页面更改时记住用户选择
- java - 如何获得权限 INSTALL_PACKAGE 和 DELETE_PACKAGE?
- docker - 运行 kompose up 时访问被拒绝错误
- python - 我的自定义烧瓶 ValidationError 不起作用