|
我试图为我的网站创建一个产品搜索,用户可以搜索各种语言的产品,如果没有完全匹配的内容,(希望)会得到模糊的搜索结果。, }, @% H1 V: C4 \6 w; [
我有一个pro_search带有列的表id,pro_id,en,de,es,fr,it。/ d. V* ?1 L# Y
该pro_id指各自表中的产品ID。
B% O5 h6 |5 z: `这些en,de,es,fr,it翻译各种语言的每个产品meta。
9 |! z# `' a2 s& M元只是由空间分隔的关键字- u/ ^9 X @: r3 b/ C
$term 是搜索词。
3 U& H' J& F8 z" O- T$lang 指用户选择的语言因此,首先,我执行了一个基本的 LIKE”# l7 Q* `7 l% E2 K0 x9 G9 `
SQL查询是否有匹配项,如果没有结果,查询所有产品并使用similar_text()根据其相似性创建一个数组
& _" T# ]; D) G& W: f* l S1 k3 I比如我搜索衬衫,如果这个产品的元数据只包含衬衫这个词,那就好了,但如果元数据包含蓝色品牌Tt恤更具解释性,为用户提供了根据品牌搜索的机会,但这意味着搜索很可能会变得模糊,而不是通过LIKESQL查询找到。4 Q3 z$ U7 A& f& ~! D1 ]
这是一项工作,但我想知道如何改进它,是否有更好的搜索方法,或者人们通常会做什么?我应该吗?meta分成每个单独的关键字,并尝试查看匹配多少个单词,而不是将术语与整个单词匹配meta匹配?. L& @& v% i) w+ _& w9 c
$ids = $params = ['%'.$term. $sql = "SELECT * FROM pro_search WHERE $lang LIKE ?"; $stmt = DB::run($sql,$params); $count = $stmt->rowCount(); if($count > 0){ // product search while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $id = $row["pro_id"]; array_push($ids,$id); show_products($ids); }else product fuzzy search $sql = "SELECT * FROM pro_search"; $stmt = DB::run($sql); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) $id = $row["pro_id"]; $result = $row[$lang]; similar_text($term,$result,$similarity); $similar_array[$similarity][] = $id; $closest_match = array_keys($similar_array); rsort($closest_match); $match_count = count($closest_match); for($i=0; $i我以前问过类似的问题,人们指出了术语和meta比较不同的方法(例如levenshtein),但我看到的一切都是两个简单的词(如苹果和橙子),这只是对于成千上万的现实生活应用程序,它足够好,用户可以搜索几乎所有的内容(如$term='literallyanything';)9 s& J! K# S8 Z, t* }. F! U! d
关键问题:
8 D; _6 s6 [6 O7 f2 |& [$ p我的元数据应该只包含产品名称或多个相关关键字(过多的关键字意味着单个单词与整个单词不太相似)?
) j# t1 T% t* d* c6 @如果我在中继数据中有多个关键字,我应该将每个关键字与搜索词进行比较吗?
) F0 |) j9 m. F2 N, m否定关键字也可能用于单个产品。
+ J, U! G8 R9 V5 i+ W/ ~ 解决方案: : o, Y1 E" R! S) `& j
你在寻找拥有QUERY
' x8 @5 P4 j$ r: [+ h% tEXPANSION的全文本搜索# s# ^* m9 u+ N8 j
MySQL通过使用LIKE运算符和正则表达式支持文本搜索。但是,当文本列很大,表中的行数增加时,使用这些方法会有一些局限性: G: W$ Y4 S* @
性能:MySQL必须扫描整个表格LIKE找到语句中的模式或正则表达中的模式。8 j0 i/ r8 ~. v3 m- J
灵活搜索:通过LIKE操作符和正则表达式搜索,很难进行灵活的搜索查询,中包含汽车而不是经典产品的产品。5 m4 _% e. P- ?- v0 T5 }! ?
相关排名:无法指定结果集中的哪一行与搜索词更相关。由于这些限制,MySQL扩展了一个非常好的功能,即所谓的全文搜索。从技术上讲,MySQL从已启用的全文搜索列单词创建索引,然后搜索索引。MySQL使用复杂的算法来确定与搜索查询相匹配的行。 M% N9 P$ i6 S4 `0 {1 Q
为此,必须使用搜索列TEXT类型,索引必须是FULLTEXT可使用类型ALTER
- {5 y* {4 |. E1 z) iTABLE或CREATE6 c8 o [7 s+ M/ V! v
INDEX如果您使用索引,请提供索引phpMyAdmin管理数据库据库,您可以在列的操作下单击更多,然后选择全文。$ \8 F6 f; H' ^3 K
之后,您可以使用MATCH3 v! M; e" V. { G' s
AGAINST语法执行搜索。MATCH()获取要搜索的列。AGAINST需要需要一个字符串和一个可选的修饰符,指示要执行的搜索类型。& n& f. |- b7 o* F c9 \
具有QUERY EXPANSION全文搜索:在某些情况下,用户希望根据自己的知识搜索信息。用户使用他们的经验来定义关键字来搜索信息,通常太短。1 U6 W4 i" R8 X0 z( u
为了帮助用户根据太短的关键字找到信息,MySQL全文搜索引擎引入了一个叫做查询扩展的概念。7 Q1 f! _' R/ b1 c9 F# k' U1 f
查询扩展用于基于自动相关反馈(或盲查询扩展)来扩展全文搜索的搜索结果。从技术上讲,在使用查询扩展时,MySQL全文搜索引擎执行以下步骤:" \) H: j5 v2 z6 ~
首先,MySQL全文搜索引擎搜索所有匹配搜索查询的行。" a% o2 M+ }1 d @( N
其次,它检查搜索结果中的所有行,并找到相关单词。
e) b2 S$ u' I1 w+ g第三,它再次搜索相关单词,而不是用户提供的原始关键字。以下示例显示了如何搜索至少一个单词的产品名称或元数据(衬衫)T恤)。
[: I) f8 }, U8 p _! QSELECT * FROM products WHERE MATCH(product_name,product_meta) AGAINST('shirt tshirt' WITH QUERY EXPANSION) |
|