根据结果序列对 PHP MySQL 搜索结果进行排名
Posted
技术标签:
【中文标题】根据结果序列对 PHP MySQL 搜索结果进行排名【英文标题】:Rank PHP MySQL search results based on result sequence 【发布时间】:2021-04-06 14:16:40 【问题描述】:我想改进我的 mysql 搜索功能。在我的汽车数据库中搜索“Fi”时,我希望 FIAT 排名第一,因为我觉得汽车品牌的排名应该高于车型版本。我想告诉 MySQL 搜索词是否与品牌的第一个字母匹配,然后优先考虑该结果。
]1
这是我当前的代码
$sql = "SELECT v.id, v.model, v.model_version, v.model_year, b.brand FROM vehicles v LEFT JOIN brands b ON v.brand_id = b.id WHERE CONCAT(b.brand, ' ', v.model, ' ', v.model_version) LIKE ? LIMIT 6";
【问题讨论】:
这与 JS、自动完成和 php 无关。您应该查看全文索引。 dev.mysql.com/doc/refman/8.0/en/fulltext-search.html. 对!这似乎是有道理的。试过这个,但它不起作用: $sql = "SELECT v.id, v.model, v.model_version, v.model_year, b.brand FROM Vehicles v LEFT JOIN Brands b ON v.brand_id = b.id WHERE MATCH( b.brand, v.model, v.model_version) 反对(?在自然语言模式中)”; 您是否已经创建了索引?你能再定义doesnt work
吗?没有给出结果,没有达到预期的排名等等?
索引是为品牌、型号和型号版本创建的。我得到的错误是“#1210 - MATCH 的参数不正确”一旦我删除品牌,我就会得到一个结果。所以不知何故,我将品牌添加到组合中是有问题的。
你能添加show create table brands
的结果吗?
【参考方案1】:
@user3783243 的评论是正确答案。如果你想用 mysql 来做,请按照这些行定义一个排名列:4 * if(b.brand like ?, 1, 0) + 2 * if(v.model like ?, 1, 0) + if(v.model_version like ?, 1, 0) as 'rank'
。它很快就会变得棘手。假设模型上有精确的马赫,但品牌上有部分匹配。部分品牌真的应该排名更高吗?
【讨论】:
谢谢你,它有效。但你是对的,它很快就会变得复杂。让你快速领略googles搜索引擎的复杂性... 如果回答了您的问题,请将其标记为已解决。【参考方案2】:我找到了我认为非常有效的最佳答案。由于全文搜索最多只能索引 4 个字符(除非您更改服务器设置),这可能很麻烦。
这是我的方法:
SELECT v.id, v.model, v.model_version, v.model_year, b.brand FROM vehicles v
LEFT JOIN brands b ON v.brand_id = b.id
WHERE (
CONCAT(b.brand, ' ', v.model, ' ', v.model_version) LIKE 'fi%' OR
CONCAT(b.brand, ' ', v.model, ' ', v.model_version) LIKE '%fi%' OR
CONCAT(b.brand, ' ', v.model, ' ', v.model_version) LIKE '%fi'
) ORDER BY case
WHEN CONCAT(b.brand, ' ', v.model, ' ', v.model_version) LIKE 'fi%' THEN 1
WHEN CONCAT(b.brand, ' ', v.model, ' ', v.model_version) LIKE '%fi%' THEN 2
WHEN CONCAT(b.brand, ' ', v.model, ' ', v.model_version) LIKE '%fi' THEN 3
ELSE 4 END
LIMIT 6
【讨论】:
在where
子句中,您只需要'%fi%'
的情况。如果您不需要搜索覆盖重叠字段,则如果您的where
子句查看与构造字段相反的单个字段,您可能会获得更好的性能。如果您需要构造列,则您的查询将使用公用表表达式进行清洁。我不知道这是否对性能有任何影响。 with select v.id, CONCAT(b.brand, ' ', v.model, ' ', v.model_version) brand_model_version select ... where brand_model_version like ...
上面应该是with t select v.id ... select id, brand_model_version from t where brand_model_version lile '%fi%' order by ...
以上是关于根据结果序列对 PHP MySQL 搜索结果进行排名的主要内容,如果未能解决你的问题,请参考以下文章