5

我有数以百万计的项目按预先计算的分数排序。每个项目都有许多布尔属性。假设总共有大约一万个可能的属性,每个项目都有十几个。

我希望能够实时(几毫秒)请求给定的前 n 个项目〜任何属性组合。

你会推荐什么解决方案?我正在寻找极具可扩展性的东西。

---
我们目前正在研究mongodb和数组索引,您是否看到任何限制?
- SolR 是一种可能的解决方案,但我们不需要文本搜索功能。

4

3 回答 3

9

如果您像这样存储对象,Mongodb 可以处理您想要的

{ score:2131, attributes: ["attr1", "attr2", "attr3"], ... }

然后下面的查询将匹配所有具有att1和attr2的项目

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr2" ] } })

但这不匹配

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr4" ] } })

查询返回一个游标,如果您希望对该游标进行排序,则只需将排序参数添加到查询中,如下所示

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr2" ] }}).sort({score:1})

查看高级查询以了解可能的情况。

适当的索引可以设置如下

db.mycol.ensureIndex({attributes:1, score:1})

您可以使用获取性能信息

db.mycol.find({ attributes: { $all: [ "attr1" ] }}).explain()

Mongo 解释了扫描了多少对象、操作花费了多长时间以及其他各种统计数据。

于 2012-05-01T07:05:57.823 回答
2

这正是Mongo可以处理的。您的属性是布尔类型的事实在这里有所帮助。下面列出了一个可能的模式:

[
    {
        true_tags:[attr1, attr2, attr3, ...],
        false_tags: [attr4, attr5, attr6, ...]
    },
]

然后我们可以索引true_tagsfalse_tags。并且使用 $in, $all, ... 查询运算符进行搜索应该是有效的。

于 2012-05-01T03:53:55.637 回答
2

Redis 将是一个完美的候选者

  • “按分数排序的数百万个项目”的“前 n 个项目”

Redis 有一个内置的数据结构,您可以从它开始:Sorted Set=> 排序集的每个成员都与分数相关联。例如,可以使用ZRANGEBYSCORE按分数排名:

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

我鼓励您查看 Sorted Set命令并了解 Redis,因为您的问题(如前所述)要求它。您当然可以在单个 Set 元素中保留任意数量的属性。


至于 MongoDB,既然您提到了数百万,除非您可以弯曲增量查询来解决您的问题,否则我不会期望亚秒级的响应。

正如@nickdos 提到的,Solr Relevancy 是一个非常强大的功能,但是属性的数量是一个问题,因为它需要将所有这些属性保存在每个项目的内存中。虽然每个人打一打可能没那么糟糕 => 试试看。

于 2012-05-01T05:52:25.877 回答