Help us shape the future of Go! Take the 2026 Go Developer Survey

estextsearch

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package estextsearch 构建短文本检索的 Elasticsearch 查询子句,仅依赖标准库。 Query(field, text) 提供基础召回,QueryExpanded(field, text) 扩展混合输入的召回。 两个入口均无需初始化或配置对象,不执行网络请求,由调用方选择召回与性能的取舍。 普通关键词、编号、部分词搜索或成本优先时选 Query;单独的跨词同义词查询也可由 Query 支持。 配置了跨词同义词且需要与编号等符号片段组合召回时选 QueryExpanded。 不触发混合规则时两个入口的 DSL 相同;触发后扩展入口可能增加 ES 执行成本。

使用示例:

clause, err := estextsearch.Query("query_text", "apple PR-PV02")
if err != nil {
	return err
}
boolQuery := map[string]any{
	"filter": []any{
		map[string]any{"term": map[string]any{"merchant_user_id": "10001"}},
	},
}
if clause != nil {
	boolQuery["must"] = []any{clause}
}
request := map[string]any{
	"query": map[string]any{"bool": boolQuery},
	"size":  20,
}
_ = request // 交给应用使用的 ES 客户端执行。

需要组合跨词同义词和编号时,可将上述构建调用替换为:

clause, err := estextsearch.QueryExpanded("query_text", "personal computer PR-PV02")
if err != nil {
	return err
}
_ = clause // 使用相同的方式嵌入请求。

两个入口使用主字段及固定后缀 .contains、.contains_unigram,调用方须确保这些字段存在。 普通文本采用全文 OR 连续包含;1~2 字符使用 unigram,至少 3 字符使用 trigram。 单字符默认支持;单段中的单字符或含标点、符号的文本只走包含,避免分词忽略关键字符。 包含使用 match_phrase、slop 0,不设 32 字符的分支切换,也不依赖 edge_ngram。

Query 的多片段采用“整句查询 OR 各片段全部命中”,保留整句全文分支的跨词同义词。 按空白分段,仅去除完全相同的片段;超过 16 个不同片段时只保留整句,不截断输入。 重复输入去重后仅剩一个片段时,仍保留“整句 OR 单片段”,避免编号或部分词漏召回。 QueryExpanded 在混合输入含连续多词普通块时,采用“整句查询 OR 块组合”:以含符号片段为边界, 普通块沿用“整块 OR 分段 AND”,符号片段作为字面 filter,各块须同时满足。 块组合已覆盖外层分段 AND 的命中,省去该冗余路径,减少重复查询与评分。 块内保留原始空白与重复词,不跨符号片段拼接同义词;最多 16 块,重复块也计数。 超过块数上限或不满足混合规则时与 Query 完全一致。编号仍是保留符号的连续包含,不是完整值相等。 不枚举块内的词组切分,同一块内跨词同义词与部分词的任意组合仍不保证召回。 全文分支沿用字段的 search_analyzer;同义词规则由索引和词典决定,不另设查询开关。

去除首尾空白后为空时返回 nil, nil,应用应省略该条件,不能将 nil 作为 query 提交。 非法字段或 UTF-8 返回错误;不限制查询长度,应用按业务需求校验输入长度与请求规模。 返回值是独立的 map,可直接合并业务请求;两个入口均可并发调用,返回值由各调用方自行管理。 查询使用 ES 原生评分,混合路径的字面 filter 不计分;多条路径命中会累加普通文本评分。 QueryExpanded 保留 Query 的命中并扩展召回,但仍有额外成本,不能保证分数、排名或 Top K 不变。 业务负责过滤、排序和分页。需要文本相关性评分时放入 query 或 bool.must。 只按时间、价格等业务字段排序且不依赖文本分数或评分阈值时,可把整个子句放入 bool.filter。 filter 保留所选入口的匹配条件及编号约束,但该子句不贡献分数;纯 filter 查询的 _score 为 0。 入口选择与是否评分相互独立;空子句仍须省略,查询缓存是否命中由 ES 决定。

templates/ 中的 JSON 由人工独立维护,用于创建索引;Go API 不生成或读取模板。 模板使用说明见 templates/README.md。

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidField 表示字段名为空、编码无效,或包含空白、控制字符、通配符。
	ErrInvalidField = errors.New("estextsearch: 字段名无效")
	// ErrInvalidUTF8 表示查询文本不是有效 UTF-8;错误不包含查询原文。
	ErrInvalidUTF8 = errors.New("estextsearch: 查询文本 UTF-8 无效")
)

Functions

func Query

func Query(field, text string) (map[string]any, error)

Query 构建文本查询子句,自动使用 field、field.contains 和 field.contains_unigram。 字段可为普通对象字段路径;调用方须确保对应 mapping 存在。 空白文本返回 nil, nil,应用应省略该条件;输入长度由应用限制。 多片段采用整句查询 OR 分段 AND;只有完全相同的片段才去重。 分析器、同义词和评分沿用 ES 配置;返回值可直接嵌入请求,每次调用均独立分配。

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/bpcoder16/pixiu/infra/estextsearch"
)

func main() {
	clause, err := estextsearch.Query("query_text", "apple PR-PV02")
	if err != nil {
		panic(err)
	}
	boolQuery := map[string]any{
		"filter": []any{
			map[string]any{"term": map[string]any{"merchant_user_id": "10001"}},
		},
	}
	if clause != nil {
		boolQuery["must"] = []any{clause}
	}
	body, err := json.Marshal(map[string]any{
		"query": map[string]any{"bool": boolQuery},
		"size":  20,
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(json.Valid(body))
}
Output:
true

func QueryExpanded

func QueryExpanded(field, text string) (map[string]any, error)

QueryExpanded 在 Query 的基础上扩展混合输入的召回,校验和返回值约定与 Query 相同。 以含符号片段分隔普通文本块,保留块内跨词同义词和符号片段的严格字面约束。 满足混合规则时采用整句 OR 块组合,省去已被块组合覆盖的外层分段 AND,减少重复评分。 不满足规则或超出块数预算时与 Query 一致;扩展召回仍有成本,分数及排名可能改变。

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL