Аннотированные отношения в Datomic

Я надеялся продолжить обсуждение этого вопроса SO и получить более подробную информацию о реализации.

Мои требования включают в себя разрешение администратору определять теги для отношения, количество которых произвольно, вовлеченные сущности произвольны, а вовлеченные сущности не являются контингентными (т. е. не Component сущности).

Для надуманного примера, User может иметь много Projects. У Project может быть много Users.

Администратор создает произвольное количество тегов для назначения связанным пользователям для каждой связи, например. Owner, Contributor, VIP и т. д. для User до Project.

Из того, что я понимаю в этом ответе, простого ref недостаточно, и мне нужно будет создать дополнительный объект, что-то вроде этого -

Соответствующий атрибут Project

:db/ident              :project/associations
:db/valueType          :db.type/ref
:db/cardinality        :db.cardinality/many

Соответствующий атрибут User

:db/ident              :user/associations
:db/valueType          :db.type/ref
:db/cardinality        :db.cardinality/many

Соответствующие Association атрибуты

:db/ident              :association/related-ents
:db/valueType          :db.type/string
:db/cardinality        :db.cardinality/many

:db/ident              :association/assoc-id
:db/valueType          :db.type/string
:db/cardinality        :db.cardinality/one

:db/ident              :association/tag
:db/valueType          :db.type/ref
:db/cardinality        :db.cardinality/one

Соответствующий атрибут Tag

:db/ident              :tag/name
:db/valueType          :db.type/string
:db/cardinality        :db.cardinality/one

Это насколько я понял. Мне не ясно, как построить сущность association идиоматически-Datomic.

Чтобы найти связанные отношения на данном Project, включая, помимо прочего, Users, а также найти отношения, где relationship tag = Contributor, я должен

  • 1) Перетащите refs на Project + User и получите данные через Associations? то есть вернуть все ассоциации, где association/related-ents содержит User-Id = foo

  • 2) Что-то совсем другое.

Полагаю, мой вопрос сводится к тому, где хранить ref для эффективного поиска? Следует ли использовать другой db.type вместо string или другую конструкцию для association, которая необходима? Нужны ли вообще project/associations и user/associations refs?

Цените любое понимание.

Обновить


Немного поразмыслив, я думаю, что споткнулся о refs различных сущностей. Мне интересно, могу ли я просто иметь associations/relatedEnts, который сам по себе является ссылкой, которая содержит 2 идентификатора Datomic db + тег и отбрасывает все остальные перечисленные атрибуты. Это идеально?

:db/ident              :association/relatedEnts
:db/valueType          :db.type/ref
:db/cardinality        :db.cardinality/many

:db/ident              :association/tag
:db/valueType          :db.type/ref
:db/cardinality        :db.cardinality/one

person nrako    schedule 20.10.2016    source источник
comment
Рассматривали ли вы возможность указания отдельных атрибутов проекта для каждой из ролей (для участников, владельцев и т. д.)?   -  person Piotrek Bzdyl    schedule 20.10.2016
comment
Да, я это учитывал. Этот маршрут теряет произвольную гибкость отношения сущностей. Опять надумано, но, например, приходит админ и решает добавить связь между Project и Location, чтобы сделать это поиском сокровищ. Возможные теги: Starting Points, Lunch, Finish Line или любое количество произвольных тегов, которые невозможно предсказать заранее.   -  person nrako    schedule 20.10.2016
comment
Новая функция, добавленная в Datomic в июне 2019 года, теперь добавляет дополнительный параметр к этому спору.   -  person mwal    schedule 24.04.2020


Ответы (1)


Когда вы определяете сущность для представления отношения между двумя другими сущностями (в вашем примере это User и Project), я бы рекомендовал установить связь между этой овеществленной сущностью отношения (вашей Association) и другими сущностями через ссылки Datomic. Это сохраняет возможность перехода от одного к другому без необходимости, например, анализировать составную строку.

Кроме того, ваш пример подсказывает мне, что вы рассматриваете возможность использования только одного объекта Association для представления отношения (отношений) между многими Users и Projects. Хотя этот подход может работать, у вас будет гораздо больше гибкости и возможностей для настройки, если вы создадите Association сущность для каждого отношения, которое вы моделируете. Если вы предпочитаете думать об этом как о проблеме моделирования графа, ваши объекты User и Project являются узлами графа, и вы создаете «сущность ребра» для каждого ребра между двумя узлами. Каждая из этих «пограничных сущностей» представлена ​​экземпляром Association, который имеет два ссылочных атрибута: один для User, а другой для Project. Затем этот Association также может иметь столько произвольных дополнительных атрибутов, сколько вы хотите, что позволяет вам прикреплять данные непосредственно к отношению (т. е. для ваших атрибутов тега или любых других данных, которые вы хотите представить об отношении).

Лучший, Маршалл

person Marshall    schedule 24.10.2016
comment
Спасибо за ответ. Думаю, я понимаю, что вы говорите. Не могли бы вы обновить свой ответ, указав детали схемы Datomic? - person nrako; 25.10.2016