在 Neomodel 中使用多个标签

bsu*_*ire 6 python neo4j neomodel

我想知道是否有办法将不同的标签与 NeoModel 的类相关联。如果没有,什么模块可以让我这样做?

我的理解是,在使用以下类声明时,“Person”是一个标签。

class Person(StructuredNode):
    name = StringProperty(unique_index=True)
    age = IntegerProperty(index=True, default=0)
Run Code Online (Sandbox Code Playgroud)

假设我想添加第二个标签,“就业”、“失业”、“学生”。

使用 Cypher,我可以使用: CREATE(p:Person:Student)

无论如何,我可以用 NeoModel 达到同样的效果吗?

注意: 根据我的研究,使用标签比使用属性 (neo4j/cypher) 产生更快的查询,这就是为什么我希望已就业/失业/学生成为标签。否则,我可以将“占领”添加为节点属性。

Pet*_*jko 7

截至 2020 年,虽然使用All \xd0\x86\xd1\x95 V\xd0\xb0\xd0\xb8\xd1\x96\xd1\x82yneomodel 4.0.1的答案不会产生预期的结果。因此, user3280193的答案是最正确的,但也有一点需要注意,所以让我详细说明一下。

\n
\n

标签黑客(不推荐!)

\n

首先让我们看看标签黑客为何存在缺陷:

\n
class Unemployed(StructuredNode):\n    __label__ = \'Person:Unemployed\'\n    name = StringProperty(unique_index=True)\n\n\nUnemployed(name=\'Carol\').save()\n
Run Code Online (Sandbox Code Playgroud)\n

如果您检查,它以后无法正确检测节点,即使它们正确保存在数据库中:

\n
print(len(Unemployed.nodes))        # prints 0\n
Run Code Online (Sandbox Code Playgroud)\n

结果1

\n

人们可能会认为,如果我们有另一个类Person,那么我们可以通过这种方式检索它 - 不幸的是不是。你自己看:

\n
class Unemployed(StructuredNode):\n    __label__ = \'Person:Unemployed\'\n    name = StringProperty(unique_index=True)\n\n\nclass Person(StructuredNode):\n    name = StringProperty(unique_index=True)\n\n\nUnemployed(name=\'Carol\').save()\n
Run Code Online (Sandbox Code Playgroud)\n

到目前为止,一切顺利,让我们尝试获取一些节点。下面的结果看起来不错。

\n
print(len(Person.nodes))  # prints 1\n
Run Code Online (Sandbox Code Playgroud)\n

然而,当我们尝试访问该节点时就会出现问题:

\n
print(Person.nodes[0])\n\n# Results in two exceptions\n#\n# Traceback (most recent call last):\n# ...\n# KeyError: frozenset({\'Person\', \'Unemployed\'})\n#\n# During handling of the above exception, another exception occurred:\n# ...\n# neomodel.exceptions.ModelDefinitionMismatch: <exception str() failed>\n
Run Code Online (Sandbox Code Playgroud)\n

我不会详细说明为什么会发生这种情况,只是简单地说 Neomodel 无法应对标签黑客攻击,因为它不是为此设计的。如果有人想了解这种行为,我建议查看neomodel.core图书馆的一部分。

\n
\n

遗产

\n

官方认为,neomodel 提倡继承混入。阅读更多内容:

\n

https://neomodel.readthedocs.io/en/latest/extending.html#inheritance \n https://neomodel.readthedocs.io/en/latest/extending.html#mixins

\n

由于mixins 不提供额外的标签,我将重点关注继承。让我们假设以下示例,我们深入了解继承的 2 个级别。

\n
class Person(StructuredNode):\n    name = StringProperty(unique_index=True)\n\n\nclass Student(Person):\n    pass\n\n\nclass Employed(Person):\n    pass\n\n\nclass EmployedStudent(Student, Employed):\n    pass\n\n\nPerson(name=\'Bob\').save()\nStudent(name=\'Will\').save()\nEmployed(name=\'John\').save()\nEmployedStudent(name=\'Kim\').save()\n
Run Code Online (Sandbox Code Playgroud)\n

结果:

\n
print(len(Person.nodes))            # 4\nprint(len(Student.nodes))           # 2\nprint(len(Employed.nodes))          # 2\nprint(len(EmployedStudent.nodes))   # 1\n
Run Code Online (Sandbox Code Playgroud)\n

结果2

\n

这具有正确的行为,但似乎产生了一种人工制品 - 标签EmployedStudent。没有简单的技巧可以摆脱这个附加标签,因为它对于自动类解析至关重要。

\n
\n

结论:OGM 有其缺点,但我随时会选择额外的冗余标签,而不是自己为我构造的每个类编写密码查询。

\n


小智 2

目前还没有一种方法可以向新模型结构化节点添加标签,但这可以通过 cypher 来完成。我也很乐意添加一种方法来执行此操作。您必须注意标签不要与类名冲突。您可以通过其 labels() 方法返回节点的标签

  • 因此我改用了 py2neo,但是 py2neo、bulbflow 和 neomodel 之间的详细比较将成为一篇有用的博客文章:) (2认同)