全文搜索

全文搜索 #

Easysearch SQL 提供了一组相关性函数,可以在 WHERE 子句中使用,将 SQL 查询与 Easysearch 强大的全文搜索能力相结合。这些函数在底层会翻译为对应的 Easysearch DSL 查询。

函数一览 #

函数等价函数底层 DSL用途
MATCH_QUERYMATCHQUERYmatch单字段全文匹配
MULTI_MATCHMULTIMATCHMULTIMATCHQUERYmulti_match多字段全文匹配
MATCH_PHRASEMATCHPHRASEMATCHPHRASEQUERYmatch_phrase短语匹配
QUERYquery_stringLucene 查询字符串
SCORESCOREQUERYSCORE_QUERYconstant_score相关性评分包装

MATCH_QUERY #

在单个文本字段上执行全文匹配查询。

语法 #

MATCH_QUERY(field, text)
-- 或
field = MATCH_QUERY(text)
参数说明
field要搜索的字段名(必须是 text 类型)
text搜索文本

示例 #

POST /_sql
{
  "query": "SELECT account_number, address FROM accounts WHERE MATCH_QUERY(address, 'Holmes')"
}

等价 DSL:

{"query": {"match": {"address": {"query": "Holmes"}}}}

结果:

account_numberaddress
1880 Holmes Lane

也可以使用等号写法:

SELECT account_number, address FROM accounts WHERE address = MATCH_QUERY('Holmes')

MULTI_MATCH #

在多个字段上同时执行全文匹配查询,支持通配符字段模式。

语法 #

MULTI_MATCH('query'='text', 'fields'='field_pattern')
参数说明示例
query搜索文本'Dale'
fields字段名或通配符模式'*name''firstname,lastname'

示例 #

搜索 firstname 或 lastname 中包含 “Dale” 的文档:

POST /_sql
{
  "query": "SELECT firstname, lastname FROM accounts WHERE MULTI_MATCH('query'='Dale', 'fields'='*name')"
}

等价 DSL:

{"query": {"multi_match": {"query": "Dale", "fields": ["*name^1.0"], "type": "best_fields"}}}

结果:

firstnamelastname
DaleAdams

MATCH_PHRASE #

匹配精确的短语序列,词项必须按顺序连续出现。

语法 #

MATCH_PHRASE(field, phrase)
参数说明
field要搜索的字段名
phrase精确短语文本

示例 #

POST /_sql
{
  "query": "SELECT account_number, address FROM accounts WHERE MATCH_PHRASE(address, '880 Holmes Lane')"
}

等价 DSL:

{"query": {"match_phrase": {"address": {"query": "880 Holmes Lane"}}}}

结果:

account_numberaddress
1880 Holmes Lane

QUERY #

使用 Lucene 查询字符串语法执行搜索,支持布尔运算、通配符、正则表达式和邻近搜索等高级查询语法。

语法 #

QUERY('query_string')

查询字符串遵循 Lucene 查询语法,常用写法包括:

写法说明
field:value指定字段搜索
AND / OR / NOT布尔运算
field:val*通配符
"exact phrase"短语搜索
field:[min TO max]范围查询

如果查询字符串包含语法错误,将抛出解析异常。

示例 #

POST /_sql
{
  "query": "SELECT account_number, address FROM accounts WHERE QUERY('address:Lane OR address:Street')"
}

等价 DSL:

{"query": {"query_string": {"query": "address:Lane OR address:Street"}}}

结果:

account_numberaddress
1880 Holmes Lane
6671 Bristol Street
13789 Madison Street

SCORE #

将全文查询包装为评分查询,使每条匹配文档带有相关性得分。使用 _score 隐式变量可以在 SELECT 或 ORDER BY 中访问该分数。

语法 #

SCORE(match_expression [, boost])
参数说明默认值
match_expression全文匹配表达式(如 MATCH_QUERY(...) 等)
boost可选的浮点权重因子1.0

示例 #

使用不同的 boost 权重区分不同匹配条件的优先级:

POST /_sql
{
  "query": "SELECT account_number, address, _score FROM accounts WHERE SCORE(MATCH_QUERY(address, 'Lane'), 0.5) OR SCORE(MATCH_QUERY(address, 'Street'), 100) ORDER BY _score"
}

结果:

account_numberaddress_score
1880 Holmes Lane0.5
6671 Bristol Street100.0
13789 Madison Street100.0

_score 字段只有在使用 SCORE 函数后才会有非零值。普通的 MATCH_QUERYWHERE 中作为过滤条件使用,不产生评分。


组合使用 #

全文搜索函数可以与普通的 SQL 条件组合使用:

-- 全文搜索 + 精确过滤
SELECT firstname, lastname, address, _score
FROM accounts
WHERE SCORE(MATCH_QUERY(address, 'Street'), 10)
  AND age > 30
ORDER BY _score DESC

-- 全文搜索 + 聚合
SELECT city, COUNT(*) AS cnt
FROM accounts
WHERE MATCH_QUERY(address, 'Street')
GROUP BY city
ORDER BY cnt DESC

相关链接 #