代码之家  ›  专栏  ›  技术社区  ›  Adam Dziendziel

关系数据库中分面搜索的有效实现

  •  16
  • Adam Dziendziel  · 技术社区  · 15 年前

    我正在尝试实现 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 软件,所以必须有一种有效的方法来执行关系数据库中的分面搜索。

    有没有人在平面搜索方面有经验,可以给一些提示?

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

    编辑:

    可在此处找到分面导航的示例: Flamenco .

    目前我有标准的三表方案(项目、标签和项目标签,如这里所述: http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html#toxi )加上一张小平面的桌子。每个标记都分配了一个方面。

    4 回复  |  直到 7 年前
        1
  •  5
  •   filiprem    15 年前

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

    也许,如果您将数据转换为维度模型,并将其提供给某个OLAP(我的意思是MDX引擎),它将运行良好。但它似乎有点太重了,而且绝对不是实时的。

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

        2
  •  5
  •   Nils Weinander    15 年前

    在我看来,关系数据库并不擅长搜索。您可以通过专用的搜索引擎(如solr/lucene)获得更好的性能。

        3
  •  2
  •   Neil McGuigan    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
    

    100000条记录,5个方面,大约150毫秒

        4
  •  0
  •   Cory House    15 年前

    关于计数,为什么要通过SQL来提取它们?无论如何,您必须在代码中迭代结果集,那么为什么不在那里计算呢?

    我目前正在开发一个面向面的搜索应用程序,它运行良好。唯一棘手的部分是设置代码,使其在到达新方面之前不输出方面。此时,输出方面和为它找到的行数。

    这种方法假定您要拉回一个所有匹配项的列表,从而拉回具有相同方面的多行。当您按方面排序这个结果时,很容易在代码中得到计数。