在 Titan 图数据库中用 List 基数更新顶点 属性 的整个值
Updating the entire value of vertex property with List cardinality in Titan graph database
我将更新列表 属性 的整个值并在 Titan 1.0 中为它设置一个新值,对于单一基数我可以使用 vertex.property("single_property",new_value)
并覆盖整个值但对于List 类型的基数,新值将添加到 属性(它不会覆盖整个值)。此外,如果我删除 属性 并添加一个新值,在同一个事务中,Titan 似乎会忽略整个操作!因此,我的问题是如何以适当的方式更新列表 属性 的整个值?
关于phani提供的解决方案,下面的代码对我不起作用,插入部分有效,但删除部分无效。
keywords = keywordExtractor.getKeywords(getId(nextVertex))
if (keywords.size() > 0) {
nextVertex.property(VertexProperty.Cardinality.single, "post_keyword", keywords.get(0));
keywords.remove(0);
for (String keyword : keywords) {
nextVertex.property(VertexProperty.Cardinality.list, "post_keyword", keyword);
}
}
nextVertex.graph().tx().commit();
另外,下面提供的Jason提供的解决方案也没有用。问题出在删除部分。
keywords = keywordExtractor.getKeywords(getId(nextVertex))
if (keywords.size() > 0) {
nextVertex.graph().traversal().V(nextVertex).properties("post_keyword").drop().iterate();
for (String keyword : keywords) {
nextVertex.property("post_keyword", keyword);
}
}
nextVertex.graph().tx().commit();
我也研究了以下解决方案;也没用。
keywords = keywordExtractor.getKeywords(getId(nextVertex))
if (keywords.size() > 0) {
Iterator<VertexProperty<Object>> iter = nextVertex.properties("post_keyword");
while(iter.hasNext()){
iter.next().remove();
}
for (String keyword : keywords) {
nextVertex.property("post_keyword", keyword);
}
}
nextVertex.graph().tx().commit();
您可以在 multi-属性 中使用 Cardinality list
来添加额外的属性。如果要删除多 属性 的现有值并添加新列表,可以执行以下操作:
gremlin> v = g.addV('name','marko','name','marko a. rodriguez').next()
==>v[0]
gremlin> g.V(v).properties('name').count() //(1)
==>2
gremlin> v.property(list, 'name', 'm. a. rodriguez') //(2)
==>vp[name->m. a. rodriguez]
gremlin> g.V(v).properties('name').count()
==>3
gremlin> g.V(v).property('name','okram') //(3)
==>v[0]
gremlin> g.V(v).properties('name')
==>vp[name->okram]
gremlin> g.V(v).values('name') //(4)
==>okram
1 => you used addV with multiple properties with same name, hence the count is 2
2 => to add additional name property to an existing vertex with existing entries, you would mention the cardinality as list. This will append the new name to the list of available names
3 => to remove all existing name entries and add a new entry, you would simply omit the cardinality from the property
method
4 => Hence you can see only one name for the same vertex.
Phani 提供了一个可靠的答案,非常适合 TinkerGraph。 Titan 中的行为略有不同,所以我的建议是先 drop()
属性,然后再向其中添加新项目。
gremlin> graph = TitanFactory.open('inmemory'); g = graph.traversal()
==>graphtraversalsource[standardtitangraph[inmemory:[127.0.0.1]], standard]
gremlin> mgmt = graph.openManagement()
==>com.thinkaurelius.titan.graphdb.database.management.ManagementSystem@71a06021
gremlin> name = mgmt.makePropertyKey('name').dataType(String.class).cardinality(Cardinality.LIST).make()
==>name
gremlin> mgmt.commit()
==>null
gremlin> v = g.addV('name','marko','name','marko a. rodriguez').next()
==>v[4312]
gremlin> g.V(v).properties('name').count()
==>2
gremlin> g.V(v).properties('name').drop().iterate()
gremlin> g.V(v).properties('name').count()
==>0
gremlin> v.property(list, 'name', 'm. a. rodriguez')
==>vp[name->m. a. rodriguez]
gremlin> g.V(v).properties('name').count()
==>1
主要问题中提供的所有方法都可以用作更新 list/set 基数 属性 整数值的解决方案。但是,有一个事实应该考虑到一个有效的解决方案。
在 Titan 1.0 中,当您在单个事务中使用后端索引(例如 ES 或 Solr)时,将调查所有的添加和删除操作,以找出不必要的删除操作。不知何故,删除一个 属性 并添加相同的 属性 将合并到 Titan 变异 class 中,因此删除操作将被忽略。对于单一基数,这种无知不是问题,因为在索引后端通过加法覆盖整个值,但对于 List/Set 基数,这将导致后端索引数据不一致。
假设在单个 titan 交易中 List/Set 基数 属性 有一个 属性 删除和相同的 属性 添加。提交部分后,gremlin 查询显示覆盖整个 属性 有效,但是如果您检查索引后端,您会发现新的 属性 被添加到旧的 属性。从Titan的角度来看,remove属性这个操作是合并的,去掉了不必要的删除!这个问题有两种解决方法,要么去掉Titan中Mutation
class中的consolidation
方法(在单基数情况下会造成不必要的操作),要么使用多事务进行加法和删除操作。我选择了第二种方案。
我将更新列表 属性 的整个值并在 Titan 1.0 中为它设置一个新值,对于单一基数我可以使用 vertex.property("single_property",new_value)
并覆盖整个值但对于List 类型的基数,新值将添加到 属性(它不会覆盖整个值)。此外,如果我删除 属性 并添加一个新值,在同一个事务中,Titan 似乎会忽略整个操作!因此,我的问题是如何以适当的方式更新列表 属性 的整个值?
关于phani提供的解决方案,下面的代码对我不起作用,插入部分有效,但删除部分无效。
keywords = keywordExtractor.getKeywords(getId(nextVertex))
if (keywords.size() > 0) {
nextVertex.property(VertexProperty.Cardinality.single, "post_keyword", keywords.get(0));
keywords.remove(0);
for (String keyword : keywords) {
nextVertex.property(VertexProperty.Cardinality.list, "post_keyword", keyword);
}
}
nextVertex.graph().tx().commit();
另外,下面提供的Jason提供的解决方案也没有用。问题出在删除部分。
keywords = keywordExtractor.getKeywords(getId(nextVertex))
if (keywords.size() > 0) {
nextVertex.graph().traversal().V(nextVertex).properties("post_keyword").drop().iterate();
for (String keyword : keywords) {
nextVertex.property("post_keyword", keyword);
}
}
nextVertex.graph().tx().commit();
我也研究了以下解决方案;也没用。
keywords = keywordExtractor.getKeywords(getId(nextVertex))
if (keywords.size() > 0) {
Iterator<VertexProperty<Object>> iter = nextVertex.properties("post_keyword");
while(iter.hasNext()){
iter.next().remove();
}
for (String keyword : keywords) {
nextVertex.property("post_keyword", keyword);
}
}
nextVertex.graph().tx().commit();
您可以在 multi-属性 中使用 Cardinality list
来添加额外的属性。如果要删除多 属性 的现有值并添加新列表,可以执行以下操作:
gremlin> v = g.addV('name','marko','name','marko a. rodriguez').next()
==>v[0]
gremlin> g.V(v).properties('name').count() //(1)
==>2
gremlin> v.property(list, 'name', 'm. a. rodriguez') //(2)
==>vp[name->m. a. rodriguez]
gremlin> g.V(v).properties('name').count()
==>3
gremlin> g.V(v).property('name','okram') //(3)
==>v[0]
gremlin> g.V(v).properties('name')
==>vp[name->okram]
gremlin> g.V(v).values('name') //(4)
==>okram
1 => you used addV with multiple properties with same name, hence the count is 2
2 => to add additional name property to an existing vertex with existing entries, you would mention the cardinality as list. This will append the new name to the list of available names
3 => to remove all existing name entries and add a new entry, you would simply omit the cardinality from the
property
method4 => Hence you can see only one name for the same vertex.
Phani 提供了一个可靠的答案,非常适合 TinkerGraph。 Titan 中的行为略有不同,所以我的建议是先 drop()
属性,然后再向其中添加新项目。
gremlin> graph = TitanFactory.open('inmemory'); g = graph.traversal()
==>graphtraversalsource[standardtitangraph[inmemory:[127.0.0.1]], standard]
gremlin> mgmt = graph.openManagement()
==>com.thinkaurelius.titan.graphdb.database.management.ManagementSystem@71a06021
gremlin> name = mgmt.makePropertyKey('name').dataType(String.class).cardinality(Cardinality.LIST).make()
==>name
gremlin> mgmt.commit()
==>null
gremlin> v = g.addV('name','marko','name','marko a. rodriguez').next()
==>v[4312]
gremlin> g.V(v).properties('name').count()
==>2
gremlin> g.V(v).properties('name').drop().iterate()
gremlin> g.V(v).properties('name').count()
==>0
gremlin> v.property(list, 'name', 'm. a. rodriguez')
==>vp[name->m. a. rodriguez]
gremlin> g.V(v).properties('name').count()
==>1
主要问题中提供的所有方法都可以用作更新 list/set 基数 属性 整数值的解决方案。但是,有一个事实应该考虑到一个有效的解决方案。
在 Titan 1.0 中,当您在单个事务中使用后端索引(例如 ES 或 Solr)时,将调查所有的添加和删除操作,以找出不必要的删除操作。不知何故,删除一个 属性 并添加相同的 属性 将合并到 Titan 变异 class 中,因此删除操作将被忽略。对于单一基数,这种无知不是问题,因为在索引后端通过加法覆盖整个值,但对于 List/Set 基数,这将导致后端索引数据不一致。
假设在单个 titan 交易中 List/Set 基数 属性 有一个 属性 删除和相同的 属性 添加。提交部分后,gremlin 查询显示覆盖整个 属性 有效,但是如果您检查索引后端,您会发现新的 属性 被添加到旧的 属性。从Titan的角度来看,remove属性这个操作是合并的,去掉了不必要的删除!这个问题有两种解决方法,要么去掉Titan中Mutation
class中的consolidation
方法(在单基数情况下会造成不必要的操作),要么使用多事务进行加法和删除操作。我选择了第二种方案。