Fork me on GitHub
#asami2020-08-03
>
plexus11:08:31

One of the things that set Asami apart seems to be have it handles attributes with multiple values. Instead of making a distinction via the schema it allows setting array values which get represented as linked lists in the graphs. Are there any ways to manipulate these like, like add/remove a single element?

quoll12:08:17

Yes. Asami takes the RDF approach. This is intentional

quoll12:08:15

But it means that if your data is structured like an entity (which usually only has one value per attribute), then you either want to use transact to insert/update the data as an entity and not with datoms, or else you need to be careful

plexus11:08:18

I also noticed that if you transact an array value, then try to transact a regular value for the same entity/attribute, it still returns the array when you query afterwards

quoll12:08:32

I’m not sure what you mean here… Did you do something like:

(transact conn [{:db/ident "mary"
                 :name "Mary"
                 :children ["Aaron", "Betty"]}])
(transact conn [{:db/ident "mary"
                 :children "Charles"}])
???

quoll12:08:30

I’m expecting that it’s something like that, since it would lead to the behavior that you state.

quoll12:08:54

If you wanted to append to the array, then at this point I’m expecting you to rewrite the array. i.e.:

(transact conn [{:db/ident "mary"
                 :children' ["Aaron" "Betty" "Charles"]}])

quoll12:08:18

But… I can see that adding to that attribute would more naturally append to the array. I could do that…

plexus14:08:14

Yeah that's exactly what I did. Just trying some stuff out to get a better feel of how Asami deals with things. In this case I actually expected it would return "charles" as a single value...

plexus14:08:58

But don't take that as a feature request, I'm just trying to test my mental model

quoll14:08:08

I’ll take this back to the main room…

quoll03:08:01

There’s a new set of behaviors….

quoll03:08:36

if you assert a set as a value, then it stores that as a multi-arity value

quoll03:08:49

if you have multiple values on an attribute, then it comes back as a set

quoll03:08:04

so if you add:

{:db/ident "anna" :age 31}
and then transact:
{:db/ident "anna" :age 32}
Then when you get the “anna” entity, it will come back with:
{:age #{31 32}}

quoll03:08:08

As already documented, if you wanted to replace it, you needed to transact:

{:db/ident "anna" :age' 32}

quoll03:08:22

But the OTHER new thing, is that you can append to arrays now

quoll03:08:26

So if you start with:

{:db/ident "anna" :age 31 :friends ["John" "Ringo" "Paul"]}
Then you can transact:
{:db/ident "anna" :friends+ "George"}
And when you get the “anna” entity again, you’ll retrieve:
{:age 31 :friends ["John" "Ringo" "Paul" "George"]}

quoll03:08:08

It’s all in asami-1.1.0-SNAPSHOT. I’ll test it more heavily in the morning, and document it before I release it as 1.1.0

quoll12:08:49

When you query with asami.core/q or when you use the asami.core/entity function?

quoll12:08:32

The entity function makes a presumption that you didn’t try to modify the data, so it’s not expecting multiple uses of an attribute

quoll12:08:39

The entity function is just looking for one value per attribute. If you have 2, then it will just return the first one that it finds. I have a ticket to instead return a set for attributes that have multiple values

quoll14:08:20

From the thread above…

quoll14:08:04

Asami features have mostly been driven by use cases. The rest of it has come about by me wanting to choose what I hoped were sensible defaults

quoll14:08:44

Since it’s schemaless, I have not tried to duplicate Datomic exactly

quoll14:08:35

I have been giving a bit of thought to what it means to add data that relates to an existing entity. Do I replace attributes? Do I append? How do I stay consistent with those cases where the attribute doesn’t exist? How do I minimize the work that’s done? After all, I can just remove all triples that pertain to an object, and then insert new ones. But that has performance costs in needing to query and then re-insert, and do I want to wear that overhead for every transaction?

quoll14:08:16

This was what drove the introduction of annotated attributes

quoll15:08:28

These force a lookup and modification of the existing structure, rather than just blindly inserting