我正在尝试获取标题包含用户输入内容的书籍。
假设我有以下书籍:
- 树木
- 飞机
- 曾几何时
假设用户输入了 letter a
,我之前使用以下查询解决了它:
SELECT title
FROM Books
WHERE title LIKE "%a%";
归还了所有的书。
然后,做了一些研究,我发现该函数比我尝试迁移它Match Against
要快得多,但是当我进行查询时令我惊讶的是:like
SELECT title
FROM Books
WHERE MATCH (title) AGAINST ('a' IN BOOLEAN MODE);
它不返回任何内容,因为它不包含完整的句子a
。我尝试查询失败:
SELECT title
FROM Books
WHERE MATCH (title) AGAINST ('*a*' IN BOOLEAN MODE);
当标题包含短语时,有什么方法可以让它返回书籍,无论是否准确?
从已经非常感谢了。
它
MATCH
AGAINST
使搜索与网络搜索引擎非常相似,也就是说,它搜索完整的单词,而不是它们的内容。现在,允许使用例如'a*'
si,因为它用于搜索以 A 开头的单词,el'*a*'
不是。在这种情况下,如果您必须使用传统的LIKE
.只要满足某些条件,该函数搜索“全文”
MATCH ( ) AGAINST ( )
匹配并且确实比使用 operator 搜索更快。主要是在包含代表搜索范围的文本元素的列上有一个类型索引。使用该模式时,不需要存在类型索引,但查找速度会较慢。只能在 5.5 及以下版本的 MyISAM 表上创建索引,从 5.6 版开始,它们已经允许在 InnoDB 表上创建。LIKE
FULLTEXT
IN BOOLEAN MODE
FULLTEXT
FULLTEXT
另一方面,全文搜索对被视为有效的单词的最小长度有限制,该长度由
ft_min_word_len
默认为 4 个字符的配置参数控制。如果更改此参数的值,则必须重新构建类型的索引FULLTEXT
。还有一个在全文搜索中被忽略的单词列表,称为停用词。现在,在模态中,
IN BOOLEAN MODE
星号只能放在字符串的末尾,这意味着包含以星号之前指示的前缀开头的单词的记录包含在结果中。换句话说AGAINST('a*' IN BOOLEAN MODE)
,它类似于LIKE 'a%'
。在这种情况下,最小长度参数无关紧要,因为前缀并不表示一个完整的单词,而只是一个前缀。在我看来,您正在寻找的功能是使用自然语言模式
AGAINST('texto tecleado por el usuario' IN NATURAL LANGUAGE MODE)
,这将生成一个按匹配因子排序的结果,该匹配因子会将包含与条件最相似的文本的记录放在开头。FULLTEXT
但是,这需要在要用于查找的列上创建索引,并具有我上面提到的限制。该模态
IN BOOLEAN MODE
提供了可用于指示单词处理的运算符:+
指示文本必须包含该单词。-
表示文本不应包含该单词。>
表示如果文本包含单词,它会赋予它更多的权重。<
表示如果文本包含该词,则赋予它较小的权重。~
表示词的权重为负,它作为一个-
平滑的,它不会消除匹配。*
与其他运算符不同,此运算符仅在末尾表示前缀。()
括号用于对条件进行分组。""
引用的文本按字面意思进行搜索,仅包含完全匹配的内容。参考文档中的更多信息。
您应该做的是您要执行搜索的字段
MATCH()
并将AGAINST()
它们更改为FULLTEXT
.例如,如果我有一个名为的表
producto
,它的字段是id_producto
,nombre_producto
和precio_producto
,你应该做的是,当你在 MySQL 中创建它时,执行以下操作:应用上一行,该字段
nombre_producto
已经可以使用MATCH()
并且AGAINST()
.您可以使用 if 结构,因此如果它是一个单词,则使用 like 并且如果它是一个短语匹配..
干杯