9. 常见ES全文搜索

match全文查询两种形式

执行流程:

  1. 确认目标字段是否analyzed
  2. 对搜索内容进行分析,得到要搜索的term
  3. 和倒排索引比对匹配,找到结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST http://IP:9200/索引名称/_search
Content-Type: application/json
{
"query": {
"match": {
"字段名称": "内容1 内容2"
}
}
}

或者

{
"query": {
"match": {
"字段名称": {"query": "内容1 内容2"}
}
}
}

这两个Elasticsearch查询条件看起来很相似,但实际上有细微的区别,主要在于它们的默认行为。

  1. 第一个查询:

    1
    2
    3
    4
    5
    6
    7
    {
    "query": {
    "match": {
    "字段名称": "内容1 内容2"
    }
    }
    }

    这是一个简单的 match 查询,其中没有指定任何额外的参数,如 operatorminimum_should_match。在这种情况下,Elasticsearch 默认使用 or 作为操作符。这意味着它会查找字段 字段名称 中包含任何这些词(”内容1”、”内容2”、”殴打”、”张三”)的文档。

  2. 第二个查询:

    1
    2
    3
    4
    5
    6
    7
    {
    "query": {
    "match": {
    "字段名称": {"query": "内容1 内容2"}
    }
    }
    }

    在这个查询中,通过使用包含 query 键的JSON对象,你实际上保留了向该 match 查询添加额外选项的能力。尽管在你提供的示例中没有指定任何额外参数,但这种格式允许你轻松地添加如 operatorminimum_should_match 等参数。如果不添加这些额外的参数,这个查询的行为和第一个查询是一样的。

总的来说,如果你不需要添加额外的参数(如 operator),那么这两个查询是等效的。但如果你计划添加更多参数或需要更高的灵活性,第二种格式更为合适。在任何情况下,最重要的是确保查询符合你的搜索需求和Elasticsearch集群的具体配置。

match全文查询使用operator=and

会要求搜索内容所有分词结果都命中的数据才返回
默认情况下operator=or

1
2
3
4
5
6
7
8
9
10
11
12
POST http://IP:9200/索引名称/_search
Content-Type: application/json
{
"query": {
"match": {
"字段名称": {
"query": "内容1 内容2",
"operator": "and"
}
}
}
}

match全文查询使用minimum_should_match进行更细粒度的精度控制

会要求搜索内容所有分词结果命中75%的数据才返回

1
2
3
4
5
6
7
8
9
10
11
12
POST http://IP:9200/索引名称/_search
Content-Type: application/json
{
"query": {
"match": {
"字段名称": {
"query": "内容1 内容2",
"minimum_should_match": "75%"
}
}
}
}

bool query的精度控制——minimum_should_match

通过minimum_should_match控制希望最少命中的数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
POST http://IP:9200/索引名称/_search
Content-Type: application/json
{
"query": {
"bool": {
"should": [
{
"match": {
"title": "brown"
}
},
{
"match": {
"title": "fox"
}
},
{
"match": {
"title": "dog"
}
}
],
"minimum_should_match": 2
}
}
}

bool query的精度控制——Boosting

boost默认是1,可以通过设置,让其具有更高的权重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
POST http://IP:9200/索引名称/_search
Content-Type: application/json
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "brown",
"boost": 3
}
}
},
{
"match": {
"title": "fox"
}
}
],
"minimum_should_match": 2
}
}
}

TF/IDF (term frequency / inverse document frequency)

出于性能原因,Elasticsearch 不会计算索引中所有文档的 IDF。 相反,每个分片都会为该分片中包含的文档计算本地 IDF。

实际上,这不是问题。 添加到索引的文档越多,本地 IDF 和全局 IDF 之间的差异就越小。 凭借现实世界中的大量数据,当地的 IDF 很快就会趋于平衡。 问题不在于相关性被破坏,而在于数据太少。

出于测试目的,我们使用一个主分片创建索引,就像我们在介绍匹配查询的部分中所做的那样。 如果只有一个分片,则本地 IDF 就是全局 IDF。

query string query

n*m叉乘搜索,命中条件类似SQL的like和ES的phrase匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"query": {
"bool": {
"should": [
{
"query_string": {
"query": "*充客* OR *张三*",
"fields": ["zasd.keyword", "column.keyword"]
}
}
]
}
}
}