gremlin python-向顶点添加多个但数量未知的属性

时间:2019-06-14 17:46:59

标签: python gremlin tinkerpop tinkerpop3 gremlin-server

我想向一个顶点添加多个属性,但是从一开始就不明确知道这些属性可能是什么。例如,假设有一个要添加为图的顶点的人,我们具有以下属性字典:

人员1

{
    "id": 1,
    "first_name": "bob",
    "age": 25,
    "height": 177
}

也许要添加另一个顶点,一个人具有以下属性:

人员2

{
    "id": 2,
    "first_name": "joe",
    "surname": "bloggs",
    "occupation": "lawyer",
    "birthday": "12 September"
}

是否可以在不显式地将属性键和值硬编码到Gremlin 属性函数中的情况下,将两个人都添加到图中?

link提供了正确方向的答案。可以在here中找到更多有用的信息。下一行反映了建议的解决方案,按预期执行,并向图中添加了一个新顶点。大。

g.addV("person").property("id", 1, "first_name", "bob", "age", 25, "height", 177).next()

但是,仅当输入经过硬编码时,它才会尝试工作。我已经将属性字典转换为(k1,v1,k2,v2,...,kn,vn)形式的值元组,但是无法以编程方式传递值。例如

tup_vals = ("id", 1, "first_name", "bob", "age", 25, "height", 177)

但是无论出于什么原因,我都不能打电话给

g.addV("person").property(*tup_vals).next()

上面的行没有引发异常,只是没有按预期执行(即未传递属性)

有人对如何以计算方式将这些属性字典传递给Gremlin属性函数有任何见识吗?


更新:幼稚/效率低下的解决方案

下面提供了一个解决方案,但这是一个糟糕的解决方案,因为它每次查询都会查询gremlin服务器。理想情况下,我想同时添加所有属性。如果id是唯一的,则只能按预期工作。

g.addV("person").property('id', id).next()

for k,v in property_dictionary[id].items():
     g.V().has('id', id).property(k, v).iterate()

答案

感谢Daniel的回答。我已经调整了他的答案(如下),以符合gremlin_python软件包。

Important note from this answer:给定上下文中的keysvalues应该从列枚举中导入-源代码here中。

from gremlin_python.process.graph_traversal import __
from gremlin_python.process.traversal import Column

persons = [{"id":1,"first_name":"bob","age":25,"height": 177}, {"id":2,"first_name":"joe","surname":"bloggs","occupation":"lawyer","birthday":"12 September"}]    

g.inject(persons).unfold().as_('entity').\
    addV('entity').as_('v').\
        sideEffect(__.select('entity').unfold().as_('kv').select('v').\
                   property(__.select('kv').by(Column.keys),
                            __.select('kv').by(Column.values)
                            )
                  ).iterate()

1 个答案:

答案 0 :(得分:1)

您可以将地图/字典插入遍历中,为每个字典创建一个顶点,然后遍历所有字典/地图条目并将它们设置为属性。在Gremlin中看起来像这样:

TypeError                                 Traceback (most recent call last)
<ipython-input-11-5b8d0425bb06> in <module>()
     11 fig = plt.figure()
     12 fig.add_subplot(111, projection=wcs)
---> 13 plt.imshow(hdu.data, origin='lower', cmap=plt.cm.viridis)

4 frames
/usr/local/lib/python3.6/dist-packages/matplotlib/pyplot.py in imshow(X, cmap, norm, aspect, interpolation, alpha, vmin, vmax, origin, extent, shape, filternorm, filterrad, imlim, resample, url, data, **kwargs)
   2697         filternorm=filternorm, filterrad=filterrad, imlim=imlim,
   2698         resample=resample, url=url, **({"data": data} if data is not
-> 2699         None else {}), **kwargs)
   2700     sci(__ret)
   2701     return __ret

/usr/local/lib/python3.6/dist-packages/astropy/visualization/wcsaxes/core.py in imshow(self, X, *args, **kwargs)
    195                 kwargs['origin'] = 'lower'
    196 
--> 197         return super().imshow(X, *args, **kwargs)
    198 
    199     def plot_coord(self, *args, **kwargs):

/usr/local/lib/python3.6/dist-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
   1808                         "the Matplotlib list!)" % (label_namer, func.__name__),
   1809                         RuntimeWarning, stacklevel=2)
-> 1810             return func(ax, *args, **kwargs)
   1811 
   1812         inner.__doc__ = _add_data_doc(inner.__doc__,

/usr/local/lib/python3.6/dist-packages/matplotlib/axes/_axes.py in imshow(self, X, cmap, norm, aspect, interpolation, alpha, vmin, vmax, origin, extent, shape, filternorm, filterrad, imlim, resample, url, **kwargs)
   5492                               resample=resample, **kwargs)
   5493 
-> 5494         im.set_data(X)
   5495         im.set_alpha(alpha)
   5496         if im.get_clip_path() is None:

/usr/local/lib/python3.6/dist-packages/matplotlib/image.py in set_data(self, A)
    632         if (self._A.dtype != np.uint8 and
    633                 not np.can_cast(self._A.dtype, float, "same_kind")):
--> 634             raise TypeError("Image data cannot be converted to float")
    635 
    636         if not (self._A.ndim == 2

TypeError: Image data cannot be converted to float

示例:

g.inject(persons).unfold().as('person').
  addV('person').as('v').
  sideEffect(select('person').unfold().as('kv').
             select('v').
               property(select('kv').by(keys), select('kv').by(values))).
  iterate()