我想知道是否可以通过 NeoModel 将不同的标签关联到一个类。如果不能,哪个模块可以让我执行此操作?
我的理解是,当使用下面的类声明时,“Person”是一个标签。
class Person(StructuredNode):
name = StringProperty(unique_index=True)
age = IntegerProperty(index=True, default=0)
假设我想添加第二个标签,“就业”、“失业”、“学生”。
有了 Cypher,我可以使用:
创建(p:Person:Student)
无论如何我可以用 NeoModel 实现同样的目标吗?
注释: 根据我的研究,使用标签比使用属性 (neo4j/cypher) 产生更快的查询,这就是为什么我希望 employed/unemployed/student 成为标签。否则,我可以将“occupation”添加为节点属性。
最佳答案
截至 2020 年,在使用 neomodel 4.0.1
时由 All Іѕ Vаиітy 回答不会产生预期的结果。因此user3280193的答案是最正确的,但并非没有小警告,所以让我详细说明。
标签黑客攻击(不推荐!)
首先让我们看看为什么标签黑客攻击是有缺陷的:
class Unemployed(StructuredNode):
__label__ = 'Person:Unemployed'
name = StringProperty(unique_index=True)
Unemployed(name='Carol').save()
如果您检查,它以后将无法正确检测节点,即使它们已正确保存在数据库中也是如此:
print(len(Unemployed.nodes)) # prints 0
有人可能会认为,如果我们有另一个类 Person
,那么我们就可以那样检索它——不幸的是不是。自己看看:
class Unemployed(StructuredNode):
__label__ = 'Person:Unemployed'
name = StringProperty(unique_index=True)
class Person(StructuredNode):
name = StringProperty(unique_index=True)
Unemployed(name='Carol').save()
到目前为止一切顺利,让我们尝试获取一些节点。以下结果看起来不错。
print(len(Person.nodes)) # prints 1
但是,当我们尝试访问该节点时,问题就会出现:
print(Person.nodes[0])
# Results in two exceptions
#
# Traceback (most recent call last):
# ...
# KeyError: frozenset({'Person', 'Unemployed'})
#
# During handling of the above exception, another exception occurred:
# ...
# neomodel.exceptions.ModelDefinitionMismatch: <exception str() failed>
我不会详细说明为什么会发生这种情况,只是说 neomodel 无法应对标签黑客攻击,因为它不是为此设计的。如果有人想了解这种行为,我建议查看库的 neomodel.core
部分。
继承
neomodel 正式提倡继承 和混合。阅读更多:
https://neomodel.readthedocs.io/en/latest/extending.html#inheritance https://neomodel.readthedocs.io/en/latest/extending.html#mixins
由于mixin 不提供额外的标签,我将重点介绍继承。让我们假设下面的例子,我们深入 2 个层次来研究继承。
class Person(StructuredNode):
name = StringProperty(unique_index=True)
class Student(Person):
pass
class Employed(Person):
pass
class EmployedStudent(Student, Employed):
pass
Person(name='Bob').save()
Student(name='Will').save()
Employed(name='John').save()
EmployedStudent(name='Kim').save()
结果:
print(len(Person.nodes)) # 4
print(len(Student.nodes)) # 2
print(len(Employed.nodes)) # 2
print(len(EmployedStudent.nodes)) # 1
这具有正确的行为,但似乎产生了一个人工制品 - 标签 EmployedStudent
。没有简单的技巧可以摆脱这个额外的标签,因为它对 automatic class resolution 至关重要。 .
结论:OGM 有其缺点,但我会随时选择额外的冗余标签,而不是为我构建的每个类自己编写密码查询。
关于python - 在 Neomodel 中使用多个标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29561962/