python - 在 Neomodel 中使用多个标签

标签 python neo4j neomodel

我想知道是否可以通过 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

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 正式提倡继承混合。阅读更多:

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

Result 2

这具有正确的行为,但似乎产生了一个人工制品 - 标签 EmployedStudent。没有简单的技巧可以摆脱这个额外的标签,因为它对 automatic class resolution 至关重要。 .


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

关于python - 在 Neomodel 中使用多个标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29561962/

相关文章:

python - 设置子图中 x 和 y 刻度的字体类型 matplotlib

python - 不知道如何无限循环这个

database - 处理和比较 cypher 和 neo4j 中的日期

python - 尝试从 Django 连接 Neo4j 数据库时出现错误

Python NeoModel 如何将查询结果作为 JSON 对象返回

python - 如何将neomodel对象转换为json? (不可 JSON 序列化)

python - 使用类来保留预定义的字符串

python - 解包 Python 的类型注解

neo4j - 如何检查neo4j中的数组属性?

database - 如何获取neo4j中节点属性的最频繁值