代码之家  ›  专栏  ›  技术社区  ›  markom

标签/关键字匹配的最佳解决方案是什么?

  •  5
  • markom  · 技术社区  · 16 年前

    我正在寻找数据库中不同记录之间关键字匹配的最佳解决方案。这是一个典型的问题,我发现了类似的问题,但没有具体的问题。

    我已经完成了全文搜索,连接和子查询,临时表,…所以我真的很想看看你们是怎么解决这么普遍的问题的。

    所以,假设我有两张桌子; Products Keywords 它们与第三张桌子相连, Products_Keywords 在经典的多对多关系中。

    如果我给你看的话 Product 在页面上录制并显示顶部 n个 相关产品,最好的选择是什么?

    我们应该考虑到记录可能共享几个关键字,这一事实应该决定顶级相关产品的顺序。

    我也愿意接受其他想法,但由于性能原因,t-sql可能是更好的解决方案。

    2 回复  |  直到 12 年前
        1
  •  3
  •   Tom H zenazn    16 年前

    我的第一张照片是这样的:

    SELECT
        P.product_id,
        COUNT(*)
    FROM
        Product_Keywords PK1
    INNER JOIN Product_Keywords PK2 ON
        PK2.keyword_id = PK1.keyword_id
    INNER JOIN Products P ON
        P.product_id = PK.product_id
    WHERE
        PK1.product_id = @product_id
    GROUP BY
        P.product_id
    ORDER BY
        COUNT(*) DESC
    

    product_关键字与product_关键字(pk2到pk1)的连接可能很粗糙,因此我无法与性能对话。这是我将开始,然后看看优化。

    作为对assaf评论的后续,需要考虑的一件事是,您可以在产品关键词和sum(pk1.weight)+sum(pk2.weight)中添加“weight”进行排名。只是一个想法。

    编辑:详细说明权重…您可以决定是否允许对关键字进行加权。不过,用于确定权重的实际方法将是一个业务决策,因此我不能在这里给您太多指导。

    例如,这个问题是关于“编程”、“关键字匹配”和“sql”。编程是非常通用的,所以如果两个问题有共同点,那可能并不意味着它们是相关的,所以你可能只把它作为1加权。sql更具体一点,所以您可以将权重设为5。关键词匹配既是问题的主要焦点,也是非常具体的,所以你可以用10来衡量。

    当然,这只是一个例子,正如我所说,权重的确切确定以及你如何评分取决于具体的业务。你可能会认为匹配关键词的数量比权重更重要,所以权重可能只是用来作为一个平局,等等。

        2
  •  0
  •   Joshua Shannon    16 年前

    嗯,也许是像下面这样的:

    select p.productId, p.name, r.rank
    from products p inner join (
    /* this inner select should bring in only products that have at least one keyword
    => shared with the requested product, and will count the actual number shared (for ranking)*/
        select related.productId, count(related.productId) as rank
        from
            products_keywords related   inner join 
            products_keywords pk ON (pk.productId = @productId  AND related.keywordId = pk.keywordId)
        where related.productId <> @productId
        group by related.productId
    ) r on p.productId = r.productId
    order by r.rank DESC /* added DESC (not in orignal solution, but needed to put higher ranked on top)*/
    

    现在我严重怀疑这是一个最佳的sql语句,但它应该完成这项工作。但我无法验证它,因为我只是从头开始编写它,没有实际的备份表,也没有要测试的数据。