How to model ordered lists in Grakn


#1

What is the best way to model an ordered list in Grakn (e.g. a wishlist such as in the example code, but ranking list items from most preferred to least preferred)? The list items should be entities in the database. The order of the items should be specific to the particular list and not related to attributes of the items in the list. In fact it would be very useful to be able to store sets of alternative orderings.

define
 gift sub entity has title;
 wishlist sub entity has title;
 title sub attribute datatype string;

 wants sub relationship has title,
 relates list,
 relates desired;

 wishlist plays list;
 gift plays desired;

insert $x isa wishlist has title "Wishlist";
insert $x isa gift has title "Peace";
insert $x isa gift has title "Love";
insert $x isa gift has title "Understanding";
insert $x isa gift has title "Money";
insert $x isa wants has title "My wishlist";

match $x isa wants has title "My wishlist"; $a has title "Peace"; $b has title "Wishlist"; insert $x (desired: $a, list:  $b);
match $x isa wants has title "My wishlist"; $a has title "Love"; $b has title "Wishlist"; insert $x (desired: $a, list: $b);
match $x isa wants has title "My wishlist"; $a has title "Understanding"; $b has title "Wishlist"; insert $x (desired: $a, list: $b);
match $x isa wants has title "My wishlist"; $a has title "Money"; $b has title "Wishlist"; insert $x (desired: $a, list: $b);

Are there any alternative ways - e.g. modelling the sequential order of each item relative to the other items versus an absolute value for each item that can then be sorted through a query?

More generally, is it possible to assign attributes to instances of roles being played (i.e. are they full ‘first class items’)? For example, a range of dates to represent when the role player played the role, or the source/provenance of the instance of the role being played?

Finally, is there a preferred way to model tables/matrices in Grakn where the elements are entities?

Thanks!


#2

Does the lack of response to this post indicate that there is no natural way to model ordered lists in Grakn?


#3

Hey @pauld,

you ask:

More generally, is it possible to assign attributes to instances of roles being played (i.e. are they full ‘first class items’)?

The answer is no, you cannot attach it to roles, but you should attach it to the instance of the relationship,
you could probably just add a ranking attribute to the wants relationship.

That is to express that a gift belongs to a specific wishlist with a specific ranking.

Also, why do you use the title attribute on the wants relationship?


#4

Hi Marco. My intention in my example was for there to be only one instance of the wants relationship - i.e. one particular list, that I’ve called ‘My wishlist’ - and for it to have 4 list members/role players (i.e. each of the members of the list). So to rank each of the role players in that relationship I would need 4 attributes and would additionally need to somehow link each ranking attribute to the particular role player. Is that correct?

I have given the wants relationship the attribute title so I can refer to and distinguish between individual relationships (i.e. specific groups of items put on a wishlist - e.g. ‘My wishlist’, ‘Paul’s wishlist’, ‘Marco’s wishlist’ etc).

Are you suggesting that instead I could create a new relationship instance for each item on the list, in which case it wouldn’t need the title attribute? Then to compile/reconstruct a wishlist I would perform a query to find all the items linked to a particular wishlist document, and use the new ranking attribute to determine the ordering?

Either way I think creating the original ranking, inserting new items and re-ordering etc could be rather fiddly. Before adding an item you would need to run a query to find out the current ranking, then work out what ranking attribute value to assign, and possibly re-define existing attribute values of other items.

Thanks

Paul


#5

@pauld

Yes I am indeed suggesting to create multiple relationship instances, more in detail:

I see now that you’re trying to build one single relationship instance (the one with title “My wishlist”) and attach a lot of roleplayers to it, i.e. after these insert statements:

match $x isa wants has title "My wishlist"; $a has title "Peace"; $b has title "Wishlist"; insert $x (desired: $a, list:  $b);
match $x isa wants has title "My wishlist"; $a has title "Love"; $b has title "Wishlist"; insert $x (desired: $a, list: $b);
match $x isa wants has title "My wishlist"; $a has title "Understanding"; $b has title "Wishlist"; insert $x (desired: $a, list: $b);
match $x isa wants has title "My wishlist"; $a has title "Money"; $b has title "Wishlist"; insert $x (desired: $a, list: $b);

you would end up having a single relationship with title “My wishlist” which has 8 roleplayers (4 times the same wishlist entity and 4 gifts).

This might not be very useful, I would instead suggest you to try with the following changes:

  • don’t attach the title attribute to the relationship wants as you will already have a roleplayer that is a wishlist, which in turn has a title
  • instead attach a ranking attribute to the relationship wants
  • instead of having 1 big relationship you should have many instances of wants relationship, one for each connection that you wish to create between a gift and a wishlist, so the insert statements would look like:
insert $x isa wishlist has title "My Wishlist";
insert $x isa gift has title "Peace";
insert $x isa gift has title "Love";
insert $x isa gift has title "Understanding";
insert $x isa gift has title "Money";

match $x isa wishlist has title "My Wishlist"; $a has title "Peace"; insert $r (desired: $a, list:  $x) isa wants has ranking 1;
match $x isa wishlist has title "My Wishlist"; $a has title "Love";  insert $r (desired: $a, list: $x) isa wants has ranking 2;
match $x isa wishlist has title "My Wishlist"; $a has title "Understanding"; insert $r (desired: $a, list: $x) isa wants has ranking 3;
match $x isa wishlist has title "My Wishlist"; $a has title "Money"; insert $r (desired: $a, list: $x) isa wants has ranking 4;

This would create 4 relationships that link the same wishlist to 4 different gifts, and on each of these relationships would will have a ranking.

You could then query for all the gifts belonging to a specific wishlist with something like:

match $x isa gift; $y isa wishlist has title 'My Wishlist'; ($x, $y) isa wants has ranking $ranking; get $x, $ranking;

This query will return all the gifts with their ranking in the My Wishlist wishlist.

Does this make sense?


#6

Yes, that makes perfect sense - thanks Marco.
Just to confirm, I assume I will be able to add the same item (gift) more than once to a particular wishlist, with a different ranking in each case. Is that correct? For some lists I will want the same item to appear more than once.


#7

@pauld

if you want to create a linked-list than you can start leveraging the fact that a relationship can be a role player in another relationship,

So you could have 1 wishlist that is in a relationship with a order relationship.

define
 gift sub entity has title;
 wishlist sub entity has title;
 title sub attribute datatype string;

order sub relationship,
relates previous,
relates next,
plays orders;  # here we are saying that order relationship plays the role orders in the ordered-wishlist relationship

 ordered-wishlist sub relationship,
  relates list,
  relates orders;

wishlist plays list;
gift plays desired, previous, next;

.... [insert entities]
.
.
.
 #define orders

match $x isa gift has title "Love"; $y isa gift has title "Money"; insert (previous: $x, next: $y) isa order;
.
.
.
match $x isa gift has title "Love"; 
$y isa gift has title "Money";  
$order (previous: $x, next:$y); $w isa wishlist has title "My Wishlist";  
insert $r ($w, $order) isa ordered-wishlist;
.
.

You can then play with the linked list when you wish to update the rankings, if this makes it easier for your use-case.


#8

Correct, you will be able to add multiple instances of same gift with different rankings


#9

That’s really useful functionality for my use case - thanks Marco. I was going to ask whether a relationship can play a role. I thought it probably could and I’m very pleased to learn that it can. I will be including lists as members of lists.