我们有一个非常简单的产品目录,可以将产品存储在mysql表中,我们需要为尽可能快速(尽可能相关)的产品构建质量搜索。产品数据库将非常大(大约500,000个产品),这就是为什么使用“喜欢”不使用索引的搜索非常慢。我们已经尝试使用快速工作的mysql全文搜索但是没有产生令人满意的结果,特别是对于使用数字的搜索(例如“LR-41”,这是一种电池类型等)。
我们的产品目录包含许多字段,但我们需要搜索的唯一字段是:
product_id = bigint
title = varchar(255)
description = text
经过多次建议后,我们终于尝试使用Sphinx搜索并进行了如下配置:
source mysearch {
type=mysql
sql_host=...
sql_user=...
sql_pass=...
sql_port=...
sql_query_pre = SET NAMES utf8
sql_query = SELECT product_id, title, description FROM products
sql_query_info = SELECT * FROM products WHERE product_id=$id
}
index fulltext {
source = mysearch
path = /var/lib/sphinxsearch/data/mysearch
docinfo = extern
mlock = 0
morphology = stem_en, metaphone
min_word_len = 1
blend_chars = +, &, U+23, -
blend_mode = trim_both
html_strip = 1
}
indexer {
mem_limit = 256M
}
searchd {
listen = 9312
# everything else set to default
}
对于网站后端,我们使用PHP,我们使用以下代码:
<?php
$sphinx = new SphinxClient();
$sphinx->SetServer('localhost', 9312);
$sphinx->SetMatchMode(SPH_MATCH_EXTENDED);
$sphinx->setFieldWeights(array(
'product_id' => 10,
'title' => 7,
'description' => 3
));
$sphinx->setLimits(0, 200, 1000, 5000);
$sphinx->SetRankingMode(SPH_RANK_PROXIMITY_BM25);
$sphinx->AddQuery($_GET['query'], "fulltext");
$results = $sphinx->RunQueries();
print_r($results);
?>
这只是一个测试搜索的演示脚本,但它会返回一个完全错误的结果,无论我用于查询 - 它匹配的产品甚至不包含我正在搜索的单词(或子字符串)。
以下是我想要实现的规则:
所以问题是 - 如何正确配置和使用sphinx + php来生成符合上述标准的搜索结果?
谢谢你!答案 0 :(得分:1)
这只是一个测试搜索的演示脚本,但无论我用于查询
,它都会返回完全错误的结果
建议从metaphone
删除morphology
。这特别使'模糊'索引 - 有点像'声音相似'。但是它与干预(即stem_en)结合起来很好 - 导致非常混乱的结果。
事实上你也可以删除词干,如果你设置前缀索引(见下文) - 如果尝试使用两者,很难检测到边缘情况。
如果查询与“product_id”匹配,则产品应排名最高(某些常用用户知道product_id并希望通过它进行搜索)
Sphinx不会在“全文”索引中包含产品ID。你需要复制它。
sql_query = SELECT product_id as id, product_id, name,...
如果查询是“Meter XY-123”,它应该匹配包含这两个词或任何这些词的所有产品(当然,包含两个字符串的产品应该排名更高)
这意味着您要进行'任意'搜索。 Sphinx默认为“ALL”搜索。更改为SPH_MATCH_ANY,
或重写查询以使其'任意'(在单词之间注入'|'或使用仲裁)
如果有人搜索“XY-123”,它应该产生与搜索“XY123”或“XY 123”相同的结果
非常狡猾。您可以尝试添加 - blend_chars
。这将是一种工作。但输入说“XY 123”与“XY123”的产品不匹配。我不认为有一个简单的解决方案。
有各种各样的统计方法可以尝试重写查询,但其性质将是不精确的。
它还要搜索子串 - 例如如果产品的标题是“Foobar 123”,即使用户搜索“foo bar 123”,“bar 123”,“foobar 12”,“foo”等,也应该退回。
需要使用min_prefix_len
启用前缀搜索,并设置enable_star = 0
但是enable_star=0
被取消了,所以也许可以使用expand_keywords=1
而不是自动为你添加星星。
结果也应按某种相关性排序
一般情况下会发生这种情况。但如果想要可以尝试更改排名模式 - 有很多选项(但需要使用扩展匹配模式)
产品也应根据找到该值的字段进行排名。
setFieldWeights
重新安抚! (你已经有了!)