Annotated relationships in Datomic

I was hoping to extend the conversation on this SO question and get some more details in terms of implementation.

My requirements include allowing an admin to define tags on a relationship, the number of which is arbitrary, the entities involved are arbitrary, and the entities involved are not contingent (ie not a Component of the entity).

For a contrived example, a User can have many Projects . A Project can have many Users .

The admin creates an arbitrary number of tags to assign to related Users per relationship eg Owner , Contributor , VIP , etc. for User to Project .

From what I understand of this answer, a simple ref is insufficient and I will need to create an additional entity, something like this-

Pertinent Project attribute

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

Pertinent User attribute

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

Pertinent Association attributes

: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

Pertinent Tag attribute

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

This is as far as I have gotten. I am not clear as to how to construct the association entity in an idiomatic-Datomic way.

To find associated relationships on a given Project , including but not limited to Users , as well as find relationships where relationship tag = Contributor , should I

  • 1) Drop the refs on Project + User and retrieve the data via Associations ? ie return all Associations where association/related-ents contains User-Id = foo

  • 2) Something entirely different.

  • I suppose my question boils down to where do I store the ref for efficient look-ups? Is there a different db.type that should be used instead of string , or a different construct for the association that is needed? Are the project/associations and user/associations refs even necessary?

    Appreciate any insight.

    Update


    After a bit more reflection, I think I tripped up on the refs on the various entities. I am wondering if I could simply have an associations/relatedEnts that is itself a ref that holds 2 Datomic db ids + tag and drop all of the other listed attrs. Is this ideal?

    :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
    

    When you're defining an entity to represent the relationship between two other entities (a User and a Project in your example), I'd recommend making the linkage from that reified relationship entity (your Association ) to the other entities via Datomic references. This preserves the ability to navigate from one to the other without having to, for example, parse a compound string.

    Additionally, your example suggests to me that you're considering only having a single Association entity to represent the relationship(s) between many Users and Projects . Although this approach can work, you will have much greater flexibility and potential for customization if you create an Association entity for every relationship you're modeling. If you prefer to think of this as a graph-modeling problem, your User and Project entities are nodes of the graph and you create an 'edge entity' for each edge between two nodes. Each of those 'edge entites' is represented by an instance of an Association that has two reference attributes, one to the User and one to the Project . Then that Association can also have as many arbitrary additional attributes as you want, allowing you to attach data directly to the relationship (ie for your tag attributes, or any other data you want to represent about the relationship).

    Best, Marshall

    链接地址: http://www.djcxy.com/p/65270.html

    上一篇: 与“重置”操作有很多关系

    下一篇: 在Datomic中注释的关系