将类似MySQL的查询转换为全文查询

将类似MySQL的查询转换为全文查询,mysql,full-text-search,Mysql,Full Text Search,好的,我有一个很好的小查询,返回评分结果。该查询当前基于LIKE,我想将其转换为全文查询,就像告诉我那样。如果分数不一样,我希望得到相同的结果顺序。我能接近任何东西的唯一方法是展开我的交叉连接 我希望能够设置特定单词组合的分数 我希望能够根据术语的位置设置权重 我不想根据搜索中的单词进行搜索。也就是说,如果用户输入“铁路员工”,我就不想在任何时候搜索“员工”。我试图从查询中只搜索术语的连续分组 如何使我的原始查询以全文为基础,并且仍然保持相对较小和有序 您可以在上看到这两个查询 原始查询-很

好的,我有一个很好的小查询,返回评分结果。该查询当前基于
LIKE
,我想将其转换为全文查询,就像告诉我那样。如果分数不一样,我希望得到相同的结果顺序。我能接近任何东西的唯一方法是展开我的交叉连接

  • 我希望能够设置特定单词组合的分数
  • 我希望能够根据术语的位置设置权重
  • 我不想根据搜索中的单词进行搜索。也就是说,如果用户输入“铁路员工”,我就不想在任何时候搜索“员工”。我试图从查询中只搜索术语的连续分组
如何使我的原始查询以全文为基础,并且仍然保持相对较小和有序

您可以在上看到这两个查询

原始查询-很好很小,分数和搜索词都在同一个位置

SELECT
  sum(score * multiplier) score,
  a.id,
  a.title
FROM
(
  SELECT 3 score, 'a railway employee' term UNION ALL
  SELECT 2 score, 'railway employee' term UNION ALL
  SELECT 2 score, 'a railway' term UNION ALL
  SELECT 1 score, 'employee' term UNION ALL
  SELECT 1 score, 'railway' term UNION ALL
  SELECT 0 score, 'a' term
) terms
CROSS JOIN
(
  SELECT 'T' TYPE, 1 multiplier
  UNION ALL SELECT 'S', 1.1
  UNION ALL SELECT 'C', 1.5
) x
INNER JOIN
(
  SELECT id, 'T' TYPE, title SEARCH FROM articles
  UNION ALL
  SELECT id, 'S' TYPE, summary SEARCH FROM articles WHERE summary <> ''
  UNION ALL
  SELECT artId, 'C' TYPE, content SEARCH FROM articleSections
) s ON s.TYPE = x.TYPE AND SEARCH LIKE concat('%', terms.term, '%')
INNER JOIN articles a ON a.id = s.id
WHERE score > 0
GROUP BY id, title
ORDER BY score DESC, title;
;

这篇评论太长了

显然,您有非常具体的评分需求,这些需求既不是自然语言搜索模式,也不是布尔搜索模式。我想知道MySQL中是否有某种隐藏机制,可以为您提供搜索关键字匹配列表,然后您可以使用该列表进行评分。我什么都不知道

如果您拥有大量语料库和相对稀少的单词(这意味着您要查找的单词在相对较少的文档中),那么您可以使用布尔模式缩小搜索空间。这样的查询类似于:

select t.id, sum(terms.score * wherefactor.factor)
from (select t.*
      . . .
      where MATCH(title, summary, content) AGAINST ('railway employee' IN BOOLEAN MODE)
     ) t left outer join
     (SELECT 3 score, 'a railway employee' term UNION ALL
      SELECT 2 score, 'railway employee' term UNION ALL
      SELECT 2 score, 'a railway' term UNION ALL
      SELECT 1 score, 'employee' term UNION ALL
      SELECT 1 score, 'railway' term UNION ALL
      SELECT 0 score, 'a' term
    ) terms cross join
    (SELECT 'T' as which, 1.0 as factor UNION ALL
     SELECT 'S', 1.1 UNION ALL
     SELECT 'C', 1.5
    ) wherefactor
    on (case when wherefacctor.which = 'T' then title 
             when wherefactor.which = 'S' then subject
             when wherefactor.which = 'C' then content
        end) like concat('%', term, '%')
group by t.id;
这将为您提供全文搜索的性能以及评分算法的细节


如果您有已知的词典,另一种可能是构建文档术语表。这样一个表将为您关心的每个文档和文档中的每个术语(称为“词典”)提供一行。有了这样的数据结构,您就可以自由地实现您选择的任何评分机制。

您的需求集有缺陷。您列出的这些“要求”是人为的,限制了您可以执行的解决方案的种类。需求应该约束解决方案,而不是指定它们。请重新思考您希望从搜索和编辑中得到什么。@LieRyan-我希望能够确定标题在结果中的方式和原因。。。为了做到这一点,我想确定如何评分以及评分的内容。。。如果我不在乎我得到了什么结果,我只会在一个简单的选择结束时进行一个WHERE匹配,然后用它来完成。@Justin808。鉴于您的评分需要,您可能根本不想使用全文搜索。或者,您可能希望使用全文搜索来查找包含关键字的行,然后使用
like
join
将分数相加。这仍然不是真正的要求。为什么要指定这个精确的排序顺序?与所有其他备选方案相比,这个精确排序算法是唯一可行的解决方案,有什么真正的原因吗?除了它在以前的实现中的方式之外,还有什么其他原因吗?为什么需要这个精确的排序顺序?基本上,如果你需要这个评分算法,那么,使用全文搜索不会给您带来太多好处。但是,中的全文搜索已经计算出匹配分数,尽管是使用不同的规则集计算的。
select t.id, sum(terms.score * wherefactor.factor)
from (select t.*
      . . .
      where MATCH(title, summary, content) AGAINST ('railway employee' IN BOOLEAN MODE)
     ) t left outer join
     (SELECT 3 score, 'a railway employee' term UNION ALL
      SELECT 2 score, 'railway employee' term UNION ALL
      SELECT 2 score, 'a railway' term UNION ALL
      SELECT 1 score, 'employee' term UNION ALL
      SELECT 1 score, 'railway' term UNION ALL
      SELECT 0 score, 'a' term
    ) terms cross join
    (SELECT 'T' as which, 1.0 as factor UNION ALL
     SELECT 'S', 1.1 UNION ALL
     SELECT 'C', 1.5
    ) wherefactor
    on (case when wherefacctor.which = 'T' then title 
             when wherefactor.which = 'S' then subject
             when wherefactor.which = 'C' then content
        end) like concat('%', term, '%')
group by t.id;