2016-02-28 93 views
6

比方说我们有食物,如数据库:ArangoDB - 如何使用图实现自定义推荐引擎?

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

而且我们有一个用户在寻找食物的建议,他们表示自己的喜好重一些标签:

foodPref = {sweet: 4, chocolate: 11} 

现在我们需要计算每个项目的得分如何以及推荐最好的项目:

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') 

我已将该问题建模为图形:sample graph

获得建议的正确方法是什么 - 自定义遍历对象或只是使用AQL进行筛选和计数,或者只是在Foxx(javascript层)中实现它?

此外,您可以帮助您为您建议的方法的示例实施?

在此先感谢!

+0

我正在用arangodb做一个食物推荐引擎,想与我联系并讨论一下吗? –

+0

当然!请发邮件给我stalemett上的Gmail。 –

回答

2

首先,让我们按照您指定的方式创建集合及其内容。我们将添加第二个用户。

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'}) 

现在,让我们以边创建边集合:

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}) 

我们的关系是这样的:

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

找出什么user1喜欢可以与此查询来完成:

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

,如果你现在要找到user1最喜欢所有的菜:

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

我们筛选了score属性。

现在,我们希望找到具有相同的优先user1做其他用户:

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

我们进入ANY方向(向前和向后),但只有有兴趣的userPreferences边缘集合,否则2 .2也会提供使用菜肴。我们现在这样做的方式。我们回到用户集合中来查找具有类似偏好的用户。

创建Foxx服务是否是一个好选择取决于个人偏好。如果您想在服务器端结合&过滤器结果,Foxx非常棒,因此客户端通信较少。如果您希望将应用程序放在微服务而不是db查询上,也可以使用它。然后您的应用程序可以保持不含数据库特定的代码 - 它只有operates with the microservice作为其后端。可能有些用户Foxx

一般来说,没有“正确”的方式 - 由于性能,代码清洁度,可伸缩性等因素,您可能会偏向于其他方式。