You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Explorer配置Elasticsearch商品搜索:自动补全与权重设置问题

Laravel Explorer + Elasticsearch 商品搜索配置解决方案

一、自动补全(edge_ngram分词器)配置

你当前使用的nGram分词器会生成所有长度的子串,对于前缀补全场景(输入"pro"匹配"product"),edge_ngram分词器更高效——它只生成前缀子串,避免不必要的计算。以下是正确的配置方式:

修改索引设置与映射

调整Product模型中的indexSettings()和mappableAs()方法:

class Product extends Model implements Explored, Aliased, IndexSettings
{
    use HasFactory, Searchable;

    protected $fillable = ['name', 'sku', 'description'];

    public function mappableAs(): array
    {
        return [
            'id' => 'keyword',
            'name'=> [
                'type' => 'text',
                'analyzer' => 'edge_ngram_analyzer', // 替换为edge_ngram分词器
                'search_analyzer' => 'standard', // 搜索时使用标准分词
            ],
            'sku' => 'text',
            'description' => [
                'type' => 'text',
                'analyzer' => 'edge_ngram_analyzer', // 可选:如果描述也需要前缀补全
                'search_analyzer' => 'standard'
            ],
        ];
    }

    public function toSearchableArray()
    {
        return[
            'id' => $this->id,
            'name' => $this->name,
            'description' => strip_tags($this->description),
            'sku' => $this->sku
        ];
    }

    public function indexSettings(): array
    {
        return [
            'settings' => [
                'analysis' => [
                    'tokenizer' => [
                        'edge_ngram_tokenizer' => [
                            'type' => 'edge_ngram',
                            'min_gram' => 2, // 最小触发补全的字符长度,按需调整
                            'max_gram' => 10, // 最大前缀长度,按需调整
                            'token_chars' => ['letter', 'digit'] // 仅保留字母和数字分词
                        ],
                    ],
                    'analyzer' => [
                        'edge_ngram_analyzer' => [
                            'type' => 'custom',
                            'tokenizer' => 'edge_ngram_tokenizer',
                            'filter' => ['lowercase']
                        ],
                    ],
                ],
            ],
        ];
    }
}

关键注意事项

  • Elasticsearch的索引设置(如分词器)创建后无法修改,修改配置后必须重建索引:
    php artisan scout:flush "App\Models\Product"
    php artisan scout:import "App\Models\Product"
    
  • min_gram和max_gram可根据业务需求调整,比如设置min_gram=2表示输入至少2个字符才触发补全。

二、权重优先级设置(标题>描述)

boost与weight的核心区别

  • boost:分为索引时boost和查询时boost,是评分乘数。索引时boost写入映射后无法修改,查询时boost可动态调整。
  • weight:固定数值,直接累加至评分,常用于bool查询的should子句或function_score查询,比boost更直观可控。

实现方式

方式1:查询时使用boost

在搜索逻辑中给name字段设置更高的boost值:

$products = Product::search($query)
    ->query(function ($builder) use ($query) {
        $builder->bool(function ($bool) use ($query) {
            $bool->should([
                ['match' => ['name' => ['query' => $query, 'boost' => 3]]],
                ['match' => ['description' => ['query' => $query, 'boost' => 1]]],
                ['match' => ['sku' => ['query' => $query, 'boost' => 2]]]
            ]);
        });
    })
    ->get();

方式2:使用function_score(推荐)

这种方式更灵活,能精确控制权重规则:

$products = Product::search($query)
    ->query(function ($builder) use ($query) {
        $builder->function_score(function ($score) use ($query) {
            $score->query(['match' => ['_all' => $query]])
                ->functions([
                    ['weight' => 3, 'filter' => ['match' => ['name' => $query]]],
                    ['weight' => 1, 'filter' => ['match' => ['description' => $query]]],
                    ['weight' => 2, 'filter' => ['match' => ['sku' => $query]]]
                ])
                ->score_mode('sum'); // 权重累加计算最终评分
        });
    })
    ->get();

三、开发经验与建议

  1. 优先验证分词效果:用Elasticsearch的_analyze API测试分词器是否正常工作,比如:
    curl -X GET "localhost:9200/_analyze" -H 'Content-Type: application/json' -d '{
        "analyzer": "edge_ngram_analyzer",
        "text": "product"
    }'
    
  2. 避免索引时boost:索引时的boost会将权重写入文档,后续调整需要重建索引,查询时的加权方式更灵活。
  3. 自动补全进阶方案:如果需要下拉式实时补全(而非搜索结果前缀匹配),可以使用Elasticsearch的completion类型,Laravel Explorer支持通过suggestable方法配置,但前缀搜索用edge_ngram更通用。
  4. 确保数据同步:修改模型配置后,必须重新同步所有商品数据到Elasticsearch,否则旧数据不会应用新的分词规则。

内容的提问来源于stack exchange,提问作者Telexx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:13:11