为什么Gremlin函数fold()会影响JSON响应中的结果?

为什么Gremlin函数fold()会影响JSON响应中的结果?,gremlin,amazon-neptune,Gremlin,Amazon Neptune,折叠如何影响gremlin服务器的JSON输出?当我展开和折叠路径内容时,会得到不同的数据结构,它会添加边和顶点属性。虽然我的目标是获得路径中的属性,但这似乎是一种奇怪的行为,我在文档中找不到有关此功能的信息 那么为什么会发生这种情况呢 g、 V'1',外路径 g、 V'1'.out.path.byunfold.fold 当我运行以下查询时:g.V'1'.out.path 但当我把g.V'1'.out.path.byexplode.fold 编辑:附加信息,我发现除了折叠之外,我还可以通过使用项

折叠如何影响gremlin服务器的JSON输出?当我展开和折叠路径内容时,会得到不同的数据结构,它会添加边和顶点属性。虽然我的目标是获得路径中的属性,但这似乎是一种奇怪的行为,我在文档中找不到有关此功能的信息

那么为什么会发生这种情况呢

g、 V'1',外路径

g、 V'1'.out.path.byunfold.fold

当我运行以下查询时:g.V'1'.out.path

但当我把g.V'1'.out.path.byexplode.fold

编辑:附加信息,我发现除了折叠之外,我还可以通过使用项目和标识获得具有属性的整个实体

所以,当我运行g.V'1'.out.path.byidentity时,我会得到路径的以下内容,与第一个查询相同

      "objects": {
        "@type": "g:List",
        "@value": [
        {
          "@type": "g:Vertex",
          "@value": {
            "id": "1",
            "label": "USER"
        }
        },
        {
          "@type": "g:Vertex",
          "@value": {
            "id": "2",
            "label": "USER"
        }
    }
  ]
}
但是当我运行g.V'1'.out.path.byproject'identity'.byidentity时,我在路径中得到的就是这个属性对象:

"objects": {
    "@type": "g:List",
    "@value": [
        {
            "@type": "g:Map",
            "@value": [
                "identity",
                {
                    "@type": "g:Vertex",
                    "@value": {
                        "id": "1",
                        "label": "USER",
                        "properties": {
                            "prop1": [
                                {
                                    "@type": "g:VertexProperty",
                                    "@value": {
                                        "id": {
                                            "@type": "g:Int32",
                                            "@value": 101839172
                                        },
                                        "value": {
                                            "@type": "g:Int32",
                                            "@value": 1
                                        },
                                        "label": "prop1"
                                    }
                                }
                            ],
                            "created_at": [
                                {
                                    "@type": "g:VertexProperty",
                                    "@value": {
                                        "id": {
                                            "@type": "g:Int32",
                                            "@value": 589742877
                                        },
                                        "value": {
                                            "@type": "g:Date",
                                            "@value": 1557226436119
                                        },
                                        "label": "created_at"
                                    }
                                }
                            ],
                        }
                    }
                }
            ]
        }

您不应获取任何图形元素的属性,即从服务器返回的顶点、边或VertexProperty-仅获取由id和标签组成的引用。因此,您在第一次遍历中看到的是正确的,而在第二次遍历中看到的使用byunfold.fold的是错误的

它实际上是我为之创建的TinkerPop中的一个bug

获得你想要的东西的正确方法是按照以下思路做一些事情:

gremlin> g.V(1).out().path().by(valueMap())
==>[[name:[marko],age:[29]],[name:[lop],lang:[java]]]
==>[[name:[marko],age:[29]],[name:[vadas],age:[27]]]
==>[[name:[marko],age:[29]],[name:[josh],age:[32]]]
gremlin> g.V(1).out().path().by(valueMap(true).by(unfold()))
==>[[id:1,label:person,name:marko,age:29],[id:3,label:software,name:lop,lang:java]]
==>[[id:1,label:person,name:marko,age:29],[id:2,label:person,name:vadas,age:27]]
==>[[id:1,label:person,name:marko,age:29],[id:4,label:person,name:josh,age:32]]
或者在TinkerPop的最新版本中,将valueMaptrue替换为:


有趣-你在使用什么图形数据库?我使用的是Neptune,所以我猜这是一种黑匣子,他们是如何实现gremlin的。实际上,展开步骤是不必要的,折叠步骤,基本上为边和顶点添加属性。我猜这不是正常的小精灵行为?有没有一种不进行折叠就得到整个顶点/边的方法?好的,我想知道它是不是有意这样做的。尽管如此,为什么不提供属性呢?例如,提供一些参数,这些参数也会加载属性。我只是在想,如果我有一个用于Gremlin的客户端,我可以定义一个具有id、标签和属性的数据结构,这样与数据的交互将更加一致?返回不带属性的引用元素有很多原因,但其中一个主要问题是存在一个沉重的顶点的风险——一个拥有大量属性数据的顶点会占用大量服务器资源进行序列化。这种情况的可能性是由TinkerPop对多属性的支持驱动的——想象一个顶点上有100多万个属性,然后你做了g.V,最后碰到了那个或更糟的,其中的几个。通过不返回属性并强制用户明确返回的内容,我们缓解了这个问题。我总是将这个问题比作SQL,在SQL中,您永远不会执行SELECT*FROM table,您将指定要返回的确切字段,因为如果您的模式曾经被修改和添加,例如,一个blob字段,你会突然选择那些数据,这可能对你的应用程序不太好。是的,我知道为什么这是默认行为,但如果有选择的话,那就好了,就像在SQL中一样。
"objects": {
    "@type": "g:List",
    "@value": [
        {
            "@type": "g:Map",
            "@value": [
                "identity",
                {
                    "@type": "g:Vertex",
                    "@value": {
                        "id": "1",
                        "label": "USER",
                        "properties": {
                            "prop1": [
                                {
                                    "@type": "g:VertexProperty",
                                    "@value": {
                                        "id": {
                                            "@type": "g:Int32",
                                            "@value": 101839172
                                        },
                                        "value": {
                                            "@type": "g:Int32",
                                            "@value": 1
                                        },
                                        "label": "prop1"
                                    }
                                }
                            ],
                            "created_at": [
                                {
                                    "@type": "g:VertexProperty",
                                    "@value": {
                                        "id": {
                                            "@type": "g:Int32",
                                            "@value": 589742877
                                        },
                                        "value": {
                                            "@type": "g:Date",
                                            "@value": 1557226436119
                                        },
                                        "label": "created_at"
                                    }
                                }
                            ],
                        }
                    }
                }
            ]
        }
gremlin> g.V(1).out().path().by(valueMap())
==>[[name:[marko],age:[29]],[name:[lop],lang:[java]]]
==>[[name:[marko],age:[29]],[name:[vadas],age:[27]]]
==>[[name:[marko],age:[29]],[name:[josh],age:[32]]]
gremlin> g.V(1).out().path().by(valueMap(true).by(unfold()))
==>[[id:1,label:person,name:marko,age:29],[id:3,label:software,name:lop,lang:java]]
==>[[id:1,label:person,name:marko,age:29],[id:2,label:person,name:vadas,age:27]]
==>[[id:1,label:person,name:marko,age:29],[id:4,label:person,name:josh,age:32]]
gremlin> g.V(1).out().path().by(valueMap().by(unfold()).with(WithOptions.tokens))
==>[[id:1,label:person,name:marko,age:29],[id:3,label:software,name:lop,lang:java]]
==>[[id:1,label:person,name:marko,age:29],[id:2,label:person,name:vadas,age:27]]
==>[[id:1,label:person,name:marko,age:29],[id:4,label:person,name:josh,age:32]]