【问题标题】:How to make MYSQL search for minimum 3 keyword matches?如何使 MYSQL 搜索至少 3 个关键字匹配?
【发布时间】:2012-02-04 16:55:55
【问题描述】:

您好,我在一次 MYSQL 搜索中遇到了一个大问题。 我的数据库表如下所示:

+------+----------+------+
|  id  | keywords | file |
+------+----------+------+

在关键字中,每个条目都有许多关键字,用逗号分隔。 (关键字 1,关键字 2...)。

在 PHP 数组中列出了一些关键字 (5-10)。 我的搜索必须从这些关键字中获得至少 3 个的所有数据库条目。 它不需要得到所有这些词!但它不能工作,只有一个。

有人可以帮我解决这个问题吗?我不知道怎么做。

【问题讨论】:

  • 那么,您正在搜索的 OTHER 表结构是什么样的……或者是这个 IT,而您只是使用一个字符串进行比较。如果是这样,关键字上下文设计不佳。
  • 没有其他表。我必须在字段中搜索:关键字。
  • @Svetlio:表结构是您的选择吗?您是如何使用逗号分隔值列的?如果您了解normalization 以及在关系表中存储逗号分隔值的问题,那就太好了:Is storing a comma separated list in a database column really that bad?
  • @ypercube 优秀链接

标签: mysql search


【解决方案1】:

这是一个挑战。蛮力方法是在带有计数的子查询中使用 UNION。

例如,

select id, file, count(*) from
  (select distinct id, file
     from file_table
       where FIND_IN_SET(keyword1, keywords)
   UNION ALL
   select distinct id, file
     from file_table
       where FIND_IN_SET(keyword2, keywords)
   UNION ALL
   select distinct id, file
     from file_table
       where FIND_IN_SET(keyword3, keywords)
   UNION ALL
   select distinct id, file
     from file_table
       where FIND_IN_SET(keyword4, keywords)
   .... MORE UNION ALL ....) as files
group by id, file
having count(*) >= 3

更有效的是,您可以有一个包含关键字和 ID 的单独表格,每行一个关键字/ID 组合。这将消除通配符搜索并提高查询效率。

下一步是转到 ElasticSearch 之类的东西,并根据结果的分数进行过滤。

【讨论】:

  • 所以,如果你搜索关键字man,它也会计算关键字womanmanhoodManemany更多...
  • 没有说这是一个很好的解决方案。只是它会起作用。解决方案是确保每个关键字都以''为后缀,因此关键字可能是'woman,man,manhood,mane',然后修改查询以每次都放入尾随逗号。跨度>
  • 是的。您还可以使用FIND_IN_SET() 函数来识别逗号分隔值。但是按照您的建议,通过制作多对多表来规范化结构是正确的方法。其他的都是小技巧。
  • 这个搜索完美。 :) 我在搜索部分单词或单词方面没有问题。
  • @Svetlio:你可以把keywords like '%keywordX%'改成FIND_IN_SET(keywordX, keywords)
【解决方案2】:

如果你有这个设置:

表格文件:

+------+-------+
| id   | file  |
+------+-------+
| 1000 | foo   |
| 1001 | bar   |
+------+-------+

表格关键字:

+----+-------+
| id | word  |
+----+-------+
|  9 | lorem |
| 10 | ipsum |
+----+-------+

表格文件关键字:

+----+--------+--------+
| id | fileid | wordid |
+----+--------+--------+
|  1 | 1000   | 9      |
|  2 | 1000   | 10     |
|  3 | 1001   | 10     |
+----+--------+--------+

您可以像这样找到带有关键字loremipsumdolor 的文件:

SELECT COUNT(DISTINCT(k.word)), f.*
FROM files f
INNER JOIN filekeywords fk
  ON fk.fileid = f.id
INNER JOIN keywords k
  ON k.id = fk.wordid
WHERE k.word in ('lorem', 'ipsum', 'dolor')  
GROUP BY f.id
HAVING COUNT(DISTINCT(k.word)) >= 3

【讨论】:

    猜你喜欢
    • 2022-11-12
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多