使用Neomodel的多个标签

时间:2015-04-10 12:50:46

标签: python neo4j neomodel

我想知道是否有办法将不同的标签与NeoModel的类关联起来。如果没有,哪个模块可以允许我这样做?

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

class Person(StructuredNode):
    name = StringProperty(unique_index=True)
    age = IntegerProperty(index=True, default=0)

让我们说我想添加第二个标签,&#34;雇用&#34;,&#34;失业&#34;,&#34;学生&#34;。< / p>

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

无论如何,我可以用NeoModel实现相同的目标吗?

注意: 根据我的研究,使用标签产生的查询比使用属性(neo4j / cypher)更快,这就是为什么我希望雇用/失业/学生成为标签。否则我会很好地添加&#34;职业&#34;作为节点属性。

4 个答案:

答案 0 :(得分:3)

目前还没有一种向新模型结构化节点添加标签的方法,但这可以通过密码完成。我也乐意添加一种方法来做到这一点。你必须要小心,标签不会与类名冲突。您可以通过label()方法

返回节点的标签

答案 1 :(得分:2)

您可以简单地攻击__label__属性

class Person(StructuredNode):
    __label__ = 'Label1:Label2:Label3'
    name = StringProperty(unique_index=True)
    age = IntegerProperty(index=True, default=0)
保存时,它会将标签Label1Label2Label3添加到已创建的节点

答案 2 :(得分:0)

这可以通过子类完成,例如:

class Person(StructuredNode):
    name = StringProperty(unique_index=True)
    age = IntegerProperty(index=True, default=0)

class PersonSub(Person):
    pass

然后,实例化子类并调用labels()方法:

psub = PersonSub(name = 'Person Sub', age=30).save()
psub.labels() #['Person', 'PersonSub']

您还可以使用密码查询来验证:

psub.cypher("MATCH (a:PersonSub) RETURN a")

答案 3 :(得分:0)

从2020年开始,在使用All Іѕ Vаиітyneomodel 4.0.1答案时不会产生预期的结果。因此,user3280193的答案是最正确的,但也有一点警告,请允许我详细说明。


标签黑客(不推荐!)

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

class Unemployed(StructuredNode):
    __label__ = 'Person:Unemployed'
    name = StringProperty(unique_index=True)


Unemployed(name='Carol').save()

如果进行检查,它以后将无法正确检测到节点,即使节点已正确保存在数据库中也是如此:

print(len(Unemployed.nodes))        # prints 0

Result 1

一个人可能以为,如果我们有另一个类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促进继承 mixins 。进一步了解:

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

由于 mixins不提供其他标签,因此我将重点介绍继承。让我们假设下面的示例,其中我们将继承深入两个层次。

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

Result 2

这具有正确的行为,但似乎产生了一个伪像-标签EmployedStudent。没有简单的技巧可以摆脱这个附加标签,因为它对automatic class resolution至关重要。


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