我正在尝试使用多标记过滤实现Faceted search或标记。在分面导航中,仅显示非空类别,并且在括号中显示类别中也匹配已应用标准的项目数。
I can get all items having assigned categories using INNER JOINs和get number of items in all category using COUNT and GROUP BY,但我不确定它将如何扩展到数百万个对象和数千个标签。特别是计数。
我知道有一些非关系型解决方案,比如Lucene + SOLR,但我也发现了一些基于闭源RDBMS的实现,据说这些实现像FacetMap.com或{Endeca或{ {3}}软件,因此必须有一种有效的方法在关系数据库中执行分面搜索。
是否有人有分面搜索的经验并且可以给出一些提示?
缓存每个类别集的计数?也许使用一些智能增量技术来更新计数器?
编辑:
可以在此处找到分面导航的示例:Flamenco。
目前我有标准的3表方案(项目,标签和items_tags,如此处所述:http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html#toxi)以及facet表。每个标签都分配了一个方面。
答案 0 :(得分:5)
IMO,关系数据库并不擅长搜索。您可以通过专用搜索引擎(如Solr / Lucene)获得更好的性能。
答案 1 :(得分:5)
我只能确认尼尔斯说的话。 RDBMS不适合多维搜索。我使用过一些智能解决方案,缓存计数器,使用触发器等等。但最终,外部专用索引器总能获胜。
可能,如果您将数据转换为维度模型并将其提供给某些OLAP [我的意思是MDX引擎] - 它将表现良好。但它似乎有点过于沉重的解决方案,而且肯定不是实时的。
相反,使用专用索引引擎(想想Lucene,想想Sphinx)的解决方案可以通过增量索引更新近乎实时地进行。
答案 2 :(得分:2)
分面搜索是一个分析问题,这意味着尺寸设计是一个不错的选择。 Aka,你搜索的东西必须是表格形式。
在分析表中包含所有感兴趣的列。
将连续值放入存储桶。
对类别或标签等“很多”项使用布尔列,例如,如果有三个标签“foo”,“bar”和“baz”,则会有三个布尔列。
使用物化视图创建分析表。
将废话索引出来。某些数据库支持此类应用程序的索引。
只过滤一次。
联合你的结果。
为常见查询构建预先聚合的物化视图。
本文也可能对您有所帮助:https://blog.jooq.org/2017/04/20/how-to-calculate-multiple-aggregate-functions-in-a-single-query/
with filtered as (
select
*
from cars_analytic
where
[some search conditions]
)
--for each facet:
select
'brand' as facet,
brand as value,
count(*) as count
from
filtered
group by
brand
union
select
'cool-tag' as facet,
'cool-tag'as value,
count(*) as count
from
filtered
where
cool_tag
union
...
-- sort at the end
order by
facet,
count desc,
value
100,000条记录,5个方面在~150毫秒
答案 3 :(得分:0)
关于计数,为什么要通过SQL拉它们?无论如何,你必须遍历代码中的结果集,那么为什么不在那里计算呢?
我正在使用这种方法在我正在开发的分面搜索应用程序中,它运行正常。唯一棘手的部分是将代码设置为不输出构面,直到它到达新的构面。此时,输出facet以及为其找到的行数。
此方法假设您正在撤回所有匹配项的列表,因此,多个行具有相同的构面。当您通过facet订购此结果时,很容易在代码中获得计数。