ArangoDB - how to implement a custom recommendation mechanism using a chart?

Let's say we have a database of food products, such as:

item1 = {name: 'item1', tags: ['mexican', 'spicy']}; item2 = {name: 'item2', tags: ['sweet', 'chocolate', 'nuts']; item3 = {name: 'item3', tags: ['sweet', 'vanilla', 'cold']; 

And we have a user who is looking for nutritional recommendations, where they indicate their weight preferences for some tags:

 foodPref = {sweet: 4, chocolate: 11} 

Now we need to calculate how well each element evaluates and recommends the best items:

 item1 score = 0 (doesn't contain any of the tags user is looking for) item2 score = 4 (contains the tag 'sweet') item3 score = 15 (contains the tag 'sweet' and 'chocolate') 

I modeled the problem as a graph: sample graph

What is the right way to get recommendations - a custom workaround or just filter and count using AQL or just implement it in Foxx (javascript layer)?

Also can you help with an approximate implementation for the proposed methods?

Thanks in advance!

+6
source share
1 answer

First, create collections and their contents as you specified them. We will add a second user.

 db._create("user") db._create("tags") db._create("dishes") db.user.save({_key: 'user1'}) db.user.save({_key: 'user2'}) db.tags.save({_key: 'sweet'}) db.tags.save({_key: 'chocolate'}) db.tags.save({_key: 'vanilla'}) db.tags.save({_key: 'spicy'}) db.dishes.save({_key: 'item1'}) db.dishes.save({_key: 'item2'}) db.dishes.save({_key: 'item3'}) 

Now create the edge collections with their edges:

 db._createEdgeCollection("userPreferences") db._createEdgeCollection("dishTags") db.userPreferences.save("user/user1", "tags/sweet", {score: 4}) db.userPreferences.save("user/user1", "tags/chocolate", {score: 11}) db.userPreferences.save("user/user2", "tags/sweet", {score: 27}) db.userPreferences.save("user/user2", "tags/vanilla", {score: 7}) db.dishTags.save("tags/sweet", "dishes/item2", {score: 4}); db.dishTags.save("tags/sweet", "dishes/item3", {score: 7}) db.dishTags.save("tags/chocolate", "dishes/item2", {score: 2}) db.dishTags.save("tags/vanilla", "dishes/item3", {score: 3}) db.dishTags.save("tags/spicy", "dishes/item1", {score: 666}) 

Our relationship is as follows:

 user-[userPreferences]->tags-[dishTags]->dishes 

find out what user1 likes with this query:

 FOR v, e IN 1..2 OUTBOUND "user/user1" userPreferences, dishTags RETURN {item: v, connection: e} 

if you now want to find all the dishes that user1 likes user1 :

 FOR v, e IN 2..2 OUTBOUND "user/user1" userPreferences, dishTags FILTER e.score > 4 RETURN v 

We filter the score attribute.

Now we want to find another user that has the same settings as user1 :

 FOR v, e IN 2..2 ANY "user/user1" userPreferences RETURN v 

We move in the ANY direction (back and forth), but are only interested in the tiny userPreferences collection, otherwise 2..2 will also use plates. The way we do it now. we return to user collections to find users with similar settings.

Whether creating a Foxx service is a good option depends on personal preference. Foxx is great if you want to combine and filter the results on the server side, so communication with clients is less. You can also use it if you want to place the application on microservices rather than on db requests. Then your application can remain free from database-specific code - it only works with the microservice as its backend. There may be times when Foxx

In general, there is no โ€œrightโ€ way - there are different ways that you may prefer over others because of performance, clean code, scalability, etc.

+2
source

All Articles