【问题标题】:Updating the entire value of vertex property with List cardinality in Titan graph database在 Titan 图数据库中使用 List 基数更新顶点属性的整个值
【发布时间】:2016-04-11 05:00:46
【问题描述】:

我将更新 list 属性的整个值并在 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();

【问题讨论】:

    标签: java graph-databases titan


    【解决方案1】:

    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
    

    更新Java code example

    【讨论】:

    • 我检查了您提供的 java 代码链接。很明显,您在删除后进行了提交。由于性能问题,我无法对每个操作进行提交,并且我想在我的应用程序的每次迭代中使用一个事务来进行所有删除/插入。
    • 使用第二个块中的代码 sn-p 再次更新了 java 示例。仍然适用于单个提交。
    • 亲爱的杰森,我终于知道发生了什么。似乎在 Titan 1.0 中,当您在单个事务中使用后端索引(例如 ES 或 Solr)时,所有添加和删除都将被调查以发现不必要的删除操作。不知何故,删除一个属性并添加相同的属性将合并到 Titan 突变类中,因此删除操作将被忽略。对于单一基数,这种无知不是问题,因为通过加法覆盖了整个值,但对于 List/Set 基数,这将导致错误情况。
    【解决方案2】:

    您可以在多属性中使用 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 => 您使用 addV 和多个同名属性,因此计数为 2

    2 => 要将附加名称属性添加到具有现有条目的现有顶点,您将提到基数作为列表。这会将新名称附加到可用名称列表中

    3 => 要删除所有现有的名称条目并添加一个新条目,您只需从 property 方法中省略基数

    4 => 因此,您只能看到同一个顶点的一个名称。

    【讨论】:

      【解决方案3】:

      在主要问题中提供的所有方法都可以用作更新列表/集基数属性整数值的解决方案。然而,有一个事实是应该考虑到有一个可行的解决方案。

      在 Titan 1.0 中,当您在单个事务中使用后端索引(例如 ES 或 Solr)时,将调查所有添加和删除操作,以发现不必要的删除操作。不知何故,删除一个属性并添加相同的属性将合并到 Titan 突变类中,因此删除操作将被忽略。对于单一基数,这种无知不是问题,因为在索引后端通过加法覆盖了整个值,但对于 List/Set 基数,这将导致后端索引数据的不一致。

      假设单次titan交易中List/Set基数属性有一个属性删除和相同属性添加。提交部分后,gremlin 查询显示覆盖整个属性有效,但如果您检查索引后端,您会发现新属性已添加到旧属性中。从 Titan 的角度来看,remove 属性操作是合并删除不必要的删除!对于这个问题有两种解决方案,或者从 Titan 中的Mutation 类中删除consolidation 方法(这会导致在单基数情况下进行不必要的操作),或者使用多个事务进行添加和删除操作。我选择了第二种解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 2016-05-26
        • 2017-09-26
        • 1970-01-01
        • 1970-01-01
        • 2013-06-28
        相关资源
        最近更新 更多