按匹配相关性排序的MySQL搜索查询

时间:2014-02-02 02:15:07

标签: mysql sql

我知道基本的MySQL查询,但我不知道如何实现准确且相关的搜索查询。

我的表格如下:

   id | kanji
   -------------
   1  | 一子
   2  | 一人子
   3  | 一私人
   4  | 一時
   5  | 一時逃れ

我已经有了这个问题:

SELECT * FROM  `definition` WHERE `kanji` LIKE '%一%'

问题在于我想从学习的字符中排序结果,一是此查询结果的必需字符。

说,用户知道这些字符:人,子,时

然后,我希望以这种方式订购结果:

   id | kanji
   -------------
   2  | 一人子
   1  | 一子
   4  | 一時
   3  | 一私人
   5  | 一時逃れ

应该首先匹配最多学习字符的结果。如果可能的话,我想首先显示仅包含学习字符的结果,然后是学习和未知字符的混合。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

根据您的偏好,按不匹配字符数量(增加)排序,然后按匹配字符数量(减少)排序。

SELECT *,
    (kanji LIKE '%人%')
  + (kanji LIKE '%子%')
  + (kanji LIKE '%時%') score
FROM kanji 
ORDER BY CHAR_LENGTH(kanji) - score, score DESC

或者,这样做的关系方式是规范化。像这样创建表:

<强> kanji_characters

kanji_id | index | character
----------------------------
      1  |     0 | 一
      1  |     1 | 子
      2  |     0 | 一
      2  |     1 | 人
      2  |     2 | 子
...

然后

SELECT kanji_id,
  COUNT(*) length,
  SUM(CASE WHEN character IN ('人','子','時') THEN 1 END) score
FROM kanji_characters
WHERE index <> 0
  AND kanji_id IN (SELECT kanji_id FROM kanji_characters WHERE index = 0 AND character = '一')
GROUP BY kanji_id
ORDER BY length - score, score DESC

虽然您未指定在重复字符的情况下应该执行的操作。上面的两个解决方案处理方式不同。

答案 1 :(得分:0)

只是一个想法,但文本索引可能有所帮助,你可以得到这样的分数:

SELECT match(kanji) against ('your search' in natural language mode) as rank 
FROM  `definition` WHERE match(`kanji`) against ('your search' in natural language mode)
order by rank, length(kanji)

诀窍是以正确的方式索引这些术语(或单词?)。我认为一般的技巧是用双引号封装每个单词并在每个单词之间留一个空格。这样,tokenizer将以您希望的方式填充索引。当然,您需要分别在进/出的路上添加/删除引号。

希望这不会让你陷入困境。