How do I read the association between Vehicle and Owner in this uml diagram? - associations

Is this saying "A Vehicle is associated with 1 Owner" - OR - does it say "A vehicle is associated with many Owners"?

Exactly. The multiplicity and roles are located to the opposite of the class. So it's "a vehicle has one owner and an owner can have multiple vehicles".

Related

How to generate recommendations for a User using Gremlin?

I am using gremlin QL on AWS Neptune Database to generate Recommendations for a user to try new food items. The problem that I am facing is that the recommendations need to be in the same cuisine as the user likes.
We are given with three different types of nodes which are- "User", "the cuisine he likes" and "the category of the cuisine" that it lies in.
In the picture above, the recommendations for "User 2" would be "Node 1" and "Node 2". However "Node 1" belongs to a different category which is why we cannot recommend that node to "User2". We can only recommend "Node 2" to the user since that is the only node that belongs to the same category as the user likes. How do I write a gremlin query to achieve the same?
Note- There are multiple nodes for a user and multiple categories that these nodes belong to.
Here's a sample dataset that we can use:
g.addV('user').property('name','ben').as('b')
.addV('user').property('name','sally').as('s')
.addV('food').property('foodname','chicken marsala').as('fvm')
.addV('food').property('foodname','shrimp diavolo').as('fsd')
.addV('food').property('foodname','kung pao chicken').as('fkpc')
.addV('food').property('foodname','mongolian beef').as('fmb')
.addV('cuisine').property('type','italian').as('ci')
.addV('cuisine').property('type','chinese').as('cc')
.addE('hasCuisine').from('fvm').to('ci')
.addE('hasCuisine').from('fsd').to('ci')
.addE('hasCuisine').from('fkpc').to('cc')
.addE('hasCuisine').from('fmb').to('cc')
.addE('eats').from('b').to('fvm')
.addE('eats').from('b').to('fsd')
.addE('eats').from('b').to('fkpc')
.addE('eats').from('b').to('fmb')
.addE('eats').from('s').to('fmb')
Let's start with the user Sally...
g.V().has('name','sally').
Then we want to find all food item nodes that Sally likes.
(Note: It is best to add edge labels to your edges here to help with navigation.)
Let's call the edge from a user to a food item, "eats". Let's also assume that the direction of the edge (they must have a direction) goes from a user to a food item. So let's traverse to all foods that they like. We'll save this to a temporary list called 'liked' that we'll use later in the query to filter out the foods that Sally already likes.
.out('eats').aggregate('liked').
From this point in the graph, we need to diverge and fetch two downstream pieces of data. First, we want to go fetch the cuisines related to food items that Sally likes. We want to "hold our place" in the graph while we go fetch these items, so we use the sideEffect() step which allows us to go do something but come back to where we currently are in the graph to continue our traversal.
sideEffect(
out('hasCuisine').
dedup().
aggregate('cuisineschosen')).
Inside of the sideEffect() we want to traverse from food items to cuisines, deduplicate the list of related cuisines, and save the list of cuisines in a temporary list called 'cuisinechosen'.
Once we fetch the cuisines, we'll come back to where we were previously at the food items. We now want to go find the related users to Sally based on common food items. We also want to make sure we're not traversing back to Sally, so we'll use simplePath() here. simplePath() tells the query to ignore cycles.
in('eats').
simplePath().
From here we want to find all food items that our related users like and only return the ones with a cuisine that Sally already likes. We also remove the foods that Sally already likes.
out('eats').
where(without('liked')).
where(
out('hasCuisine').
where(
within('cuisineschosen'))).
values('foodname')
NOTE: You may also want to add a dedup() here after out('eats') to only return a distinct list of food items.
Putting it altogether...
g.V().has('name','sally').
out('eats').aggregate('liked').
sideEffect(
out('hasCuisine').
dedup().
aggregate('cuisineschosen')).
in('eats').
simplePath().
out('eats').
where(without('liked')).
where(
out('hasCuisine').
where(
within('cuisineschosen'))).
values('foodname')
Results:
['kung pao chicken']
At scale, you may need to use the sample() or coin() steps in Gremlin when finding related users as this can fan out really fast. Query performance is going to be based on how many objects each query needs to traverse.

How to query Gremlin when multiple connections between nodes are present

I'm trying to build a suggestion engine using Gremlin but I'm having a hard time trying to understand how to create a query when multiple nodes are connected by different intermediate nodes.
Playground:
https://gremlify.com/alxrvpfnlo9/2
Graph:
In this simple example I have two users, both like cheese and bread. But User2 also likes sandwiches, which seems a good suggestion for User1 as he shares some common interests with User2
The question I'm trying to answer is: "What can I suggest to User1 based on what other users like?"
The answer should be: Everything that other users that like the same things as User1 likes, but excluding what User1 already like. In this case it should return a sandwich
So far I have this query:
g.V(2448600).as('user1')
.out().as('user1Likes')
.in().where(neq('user1')) // to get to User2
.out().where(neq('user1Likes')) // to get to what User2 likes but excluding items that User1 likes
Which returns:
Sandwich, bread, Sandwich (again), cheese
I think that it returns that data because it walks through the graph by the Cheese node first, so Bread is not included in the 'user1Likes' list, thus not excluded in the final result. Then it walks through the Bread node, so cheese in this case is a good suggestion.
Any ideas/suggestions on how to write that query? Take into consideration that it should escalate to multiple users-ingredients
I suggest that you model your problem differently. Normally the vertex label is used to determine the type of the entity. Not to identify the entity. In your case, I think you need two vertex labels: "user" and "product".
Here is the code that creates the graph.
g.addV('user').property('name', 'User1').as('user1').
addV('user').property('name', 'User2').as('user2').
addV('product').property('name', 'Cheese').as('cheese').
addV('product').property('name', 'Bread').as('bread').
addV('product').property('name', 'Sandwiches').as('sandwiches').
addE('likes').from('user1').to('cheese').
addE('likes').from('user1').to('bread').
addE('likes').from('user2').to('cheese').
addE('likes').from('user2').to('bread').
addE('likes').from('user2').to('sandwiches')
And here is the traversal that gets the recommended products for "User1".
g.V().has('user', 'name', 'User1').as('user1').
out('likes').aggregate('user1Likes').
in('likes').
where(neq('user1')).
dedup().
out('likes').
where(without('user1Likes')).
dedup()
The aggregate step aggregates all the products liked by "User1" into a collection named "user1Likes".
The without predicate passes only the vertices that are not within the collection "user1Likes".

How to classify Wikidata items?

I am trying to classify items into the main categories supported by Wikidata:
Generic, Person, Organization, Events, Works, Terms, Place, Others.
These categories are listed here:
https://www.wikidata.org/wiki/Wikidata:List_of_properties
I could not find a property that specifies the main category. I looked into
the P31 "instance of" property and P279 "subclass of" but they are not what I need.
For example for "IBM" the P31 returns "public company" and "software house" and for "Swiss International Air Lines" it returns "airline".
So I cannot tell that they are both organizations.
Is there a way to do this?
One option would be to check the properties of an item, so
if an item has the P21 "sex or gender" then it's a human (or animal).
But I don't think that is stable since no property is mandatory.
I'm using the Wikidata Toolkit for my queries.
Wikidata used to have a main type property but it was deleted in favour of instance of and a more flexible schema.
You can see lots of archived discussion about the main type at https://www.wikidata.org/wiki/Property_talk:P107
You probably want to take a look at the SPARQL endpoint at http://query.wikidata.org
Q4830453 is business enterprise / company.
To find all items that are a company or a subclass of company just do:
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT DISTINCT ?item
WHERE {
?item wdt:P31/wdt:P279* wd:Q4830453
}
The query takes a little time, there are currently 150k results.

Symfony2, Doctrine2, Entity Mapping

I have three tables such as A, B and C. There is ManyToMany relation from table A to table B.
At the same time Table C stores the relations between table A and B.
I want a connection between the tables. For example i want to print a data in table A which relates with table B. It's ok but when i want to take it to the next level and print a data in table A which relates with table B and which relates in table C, it doesn't consider the second condition.
That's my problem.
For better understanding
A: Tv Shows
B: Actors
C: Roles
I want to display role of an actor who acts in a certain tv show. But it returns me all roles the actor has played before (Including other tv shows). But i want the result to turn me as just one role (just one tv show)
Tv Show (1st filter) > Actor (2nd filter) > Role (Result)
Problem: I can't apply 1st filter to results.
Thanks in advance.
What you want to do is to allow the role table to act as the bridge between shows and actors.
Shows 1:many Roles many:1 Actors
So when you link Show and Actor you specify which role an actor plays for a given show. Drop the Doctrine 2 many to many relation between Show and Actor and replace with two 1:many relations with roles.
After that the queries will be easy.

How to add additional field to drupal organic group 'User and Group' relation?

Im using Drupal Organic group module and I want to create a group and need to assign users (filter by perticular role) to that group. I have done that part easily but the problem is that, I need to add aditional note on per each group user relation.
Lets say there is a group called "School Prefects" and need to add users to that group whos role is student. In here I need to put a small description for each relation.
Please help me to figure this out.
Thanks in advance.
I will probably deal with the same problem soon.
I think a possible workaround is to use the relation module and
the rules module. You could set up a rule to create a relation
each time a user is assigned to a group, or something like that.
Relations made by the relation module are fieldable. But it would be
maybe better to add a field to the og user-group relation directly.
Update: now that I tackled the issue, I have a different solution. We don't need to add new relations, the og_membership shipped standard with og is all that we need. This is how I did it.
I created a new membership type from admin/config/group/group-membership. It's a fildable entity so I added the required fields: in your case it will be "description".
Then I changed the used membership type per user, I did it in admin/config/people/accounts/fields/og_user_node (I needed to change the field "group membership" in user account).
So, now when you (or a group administrator) go to "manage group page" (clicking the group tab in group node), where you can add new people or manage members, either way you can edit your custom field "description" on each membership users-group.
Besides, you can clone the "og members" view adding the field "description", so in people panel in the group homepage we see name + description.
I my use-case I had to see (per group member): name, role, start date, end date. E.g. John Doe, president, from 1997 to 2003.

Resources