Использование нескольких меток с Neomodel
Я хотел бы знать, есть ли способ связать различные метки с классом с NeoModel. Если нет, какой модуль может позволить мне сделать это?
Насколько я понимаю, при использовании следующего объявления класса "Person" является меткой.
class Person(StructuredNode):
name = StringProperty(unique_index=True)
age = IntegerProperty(index=True, default=0)
Допустим, я хотел бы добавить второй ярлык: "Занят", "Безработный", "Студент".
С Cypher я мог бы использовать: CREATE(p:Person:Student)
Есть ли в любом случае я могу добиться того же с NeoModel?
Примечания. Из моих исследований, связанных с метками, можно получить более быстрые запросы, чем со свойствами (neo4j/cypher), поэтому я бы хотел, чтобы работающие / безработные / студенты были метками. В противном случае было бы неплохо добавить "занятие" как свойство узла.
2 ответа
В настоящее время нет способа добавления меток в структурный узел neomodel, однако это можно сделать с помощью шифра. Я был бы рад добавить метод, чтобы сделать это также. Вы должны быть осторожны, чтобы метка не конфликтовала с именем класса. Вы можете вернуть метки узла с помощью метода label ().
По состоянию на 2020 год при использовании
neomodel 4.0.1
ответ Marty не дает желаемого результата. Поэтому ответ от 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'})
#
# Duringhandling 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
Поскольку миксины не предоставляют дополнительных меток, я сосредоточусь на наследовании. Давайте рассмотрим следующий пример, где мы углубляемся в наследование на два уровня.
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
. Нет простого способа избавиться от этой дополнительной метки, поскольку она важна для автоматического разрешения классов.
Вывод: у OGM есть свои минусы, но я бы в любое время выбрал дополнительную избыточную метку вместо написания шифровальных запросов для каждого создаваемого мной класса.
Вы можете просто взломать __label__
имущество,
class Person(StructuredNode):
__label__ = 'Label1:Label2:Label3'
name = StringProperty(unique_index=True)
age = IntegerProperty(index=True, default=0)
при сохранении добавит ярлыки Label1
, Label2
, а также Label3
на созданный узел
Это можно сделать с помощью подклассов, например:
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")