ArangoDB - 如何使用图实现自定义推荐引擎?

7
假设我们有一个食品数据库,其中包括以下内容:
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层)中实现它?
此外,您能否提供所建议方法的示例实现?
谢谢!

我正在使用Arangodb开发一个美食推荐引擎,希望能与你取得联系并讨论一下? - Lewis Diamond
当然可以!请发送电子邮件至stalemett@gmail.com - Stan Lee
1个回答

3

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

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

我们可以朝任何方向(前进和后退),但只对userPreferences边缘集合感兴趣,否则2..2也会给我们提供菜肴。我们现在的做法是回到用户集合中查找具有类似喜好的用户。
创建Foxx服务是否是一个好选择取决于个人喜好。如果您想在服务器端组合和过滤结果,以减少客户端通信,则Foxx非常适合。您还可以使用它,如果您喜欢将应用程序放在微服务而不是数据库查询之上。然后,您的应用程序可能保持免于特定于数据库的代码 - 它仅作为其后端与微服务进行交互。可能存在使用Foxx的用例。
一般来说,没有“正确”的方法 - 有不同的方法,您可能会因为性能、代码清晰度、可扩展性等而更喜欢其中的某些方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接