在关系数据库中高效实现分面搜索

Ada*_*iel 17 sql database tagging database-design faceted-search

我正在尝试使用多标签过滤实现分面搜索或标记.在分面导航中,仅显示非空类别,并且在括号中显示类别中也匹配已应用标准的项目数.

我可以有使用内部连接分配类的所有项目,并得到使用COUNT和GROUP BY在所有类别的项目数,但我不知道怎么会扩展到数百万的标签对象和数千个.特别是计数.

我知道有一些非关系解决方案,如Lucene + SOLR,但我发现一些基于闭源RDBMS的实现,据说是像FacetMap.comEndeca软件这样的企业实力,所以必须有一个在关系数据库中执行分面搜索的有效方法.

有没有人有分面搜索的经验,可以提供一些提示?

缓存每个类别集的计数?也许使用一些智能增量技术来更新计数器?

编辑:

可以在此处找到分面导航的示例:弗拉门戈.

目前我有标准的3表方案(项目,标签和items_tags,如下所述:http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html#toxi )加上一个表对于方面.每个标签都分配了一个方面.

Nei*_*gan 7

分面搜索是一个分析问题,这意味着维度设计是一个不错的选择。也就是说,您搜索的内容必须采用表格形式。

在分析表中包含所有感兴趣的列。

将连续值放入桶中。

对“许多”项目(例如类别或标签)使用布尔列,例如,如果有三个标签“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
Run Code Online (Sandbox Code Playgroud)

约 150 毫秒内包含 5 个方面的 100,000 条记录


fil*_*rem 6

我只能确认尼尔斯说的话.RDBMS不适合多维搜索.我使用过一些智能解决方案,缓存计数器,使用触发器等等.但最终,外部专用索引器总能获胜.

可能,如果您将数据转换为维度模型并将其提供给某些OLAP [我的意思是MDX引擎] - 它将表现良好.但它似乎有点太沉重的解决方案,它绝对不是实时的.

相反,具有专用索引引擎的解决方案(想想Lucene,想想Sphinx)可以通过增量索引更新近乎实时地进行.


Nil*_*der 5

IMO,关系数据库并不擅长搜索.您可以通过专用搜索引擎(如Solr/Lucene)获得更好的性能.