elasticsearch学习6--Full text queries全文检索之match query

首先创建一个index

PUT /test_001
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 1
    }
  },
  "mappings": {
    "_doc": {
      "dynamic": false,
      "properties": {
        "id": {
          "type": "integer"
        },
        "content": {
          "type": "keyword",
          "fields": {
            "field1": {
              "type": "text",
              "analyzer": "ik_max_word",
              "search_analyzer": "ik_max_word"
            },
            "field2": {
              "type": "text",
              "analyzer": "ik_smart"
            }
          }
        },
        "createAt": {
          "type": "date"
        }
      }
    }
  }
}

简单解释下,content字段的映射:【就是一个字段配置多个分词器】

"content": {
  "type": "keyword", # 默认为 keyword类型
  "fields": {
    "field1": { # 创建content的子字段,名为field1
      "type": "text",
      "analyzer": "ik_max_word", # 字段field1的倒排序索引分词器为ik_max_word
      "search_analyzer": "ik_max_word" # 检索关键词的分词器为ik_max_word
    },
    "field2": {  # 创建content的子字段,名为field2
      "type": "text",
      "analyzer": "ik_smart" # 字段field2的倒排序索引分词器为ik_smart
         # 字段field2的检索关键词的分词器默认为ik_smart
    }
  }
}

现在往这个index中添加数据

POST _bulk
{ "index" : { "_index" : "test_001", "_type" : "_doc", "_id" : "1" } }
{ "id" : 1,"content":"关注我,系统学编程" }
{ "index" : { "_index" : "test_001", "_type" : "_doc", "_id" : "2" } }
{ "id" : 2,"content":"系统学编程,就关注我" }
{ "index" : { "_index" : "test_001", "_type" : "_doc", "_id" : "3" } }
{ "id" : 3,"content":"系统编程,求关注" }

1)使用 content 的默认字段检索【keword】

# 1、发现查询不到结果
POST /test_001/_doc/_search
{
  "query":{
    "match":{
      "content":"系统学"
    }
  }
}

# 2、查询到id = 1 的文档
POST /test_001/_doc/_search
{
  "query":{
    "match":{
      "content":"关注我,系统学编程"
    }
  }
}

因为content的类型是keyword,在存入时不会被分词,其内容只能在作为一个整体时被查询到(如上面的2)。

2)使用 content.field1字段检索【ik_max_word】

# 1、会检索出所有结果
POST /test_001/_doc/_search
{
  "query":{
    "match":{
      "content.field1":"系统学"
    }
  }
}
# 2、改变检索分词器为ik_smart,只能检索到 文档1和文档2
POST /test_001/_doc/_search
{
  "query": {
    "match": {
      "content.field1": {
        "query": "系统学",
        "analyzer": "ik_smart"
      }
    }
  }
}

field1字段在创建index的时候指定了倒排索引分词器和检索关键字分词器都为ik_max_word,在检索时会将【系统学】分词为三个Token,【系统学、系统、学】,我们存入的数据中只要匹配到其中的一个就会被检索出来。

当我们将field1的检索关键字分词器改为ik_smart时,【系统学】只能分词为一个Token【系统学】,我们存入的数据中只有匹配到【系统学】才会被检索出来。

在这里插入图片描述
在这里插入图片描述

3)match的核心参数:operator ——控制Token之间的逻辑关系,or/and

# 1、不配置,使用默认值or,得到文档1和文档2
POST /test_001/_doc/_search
{
  "query": {
    "match": {
      "content.field2": {
        "query": "系统学es"
      }
    }
  }
}
# 2、and,查询不到结果
POST /test_001/_doc/_search
{
  "query": {
    "match": {
      "content.field2": {
        "query": "系统学es",
        "operator":"and"
      }
    }
  }
}

field2,默认使用ik_smart检索分词器,所以检索词“系统学es”被分词为【系统学、es】两个Token,【语句1】的operator默认值为or,所以文档1和2可以被检索到;【语句2】的operator的值是and,也就是需要同时包含【系统学、es】这两个Token才行,所以没有结果。

4)match的核心参数:zero_terms_query——停顿词检索

首先创建一个分词器为stop的index,stop分词器会将分词之后的停顿词过滤。

PUT /test002
{
  "mappings": {
    "_doc": {
      "properties": {
        "message": {
          "type": "text",
          "analyzer": "stop"
        }
      }
    }
  }
}

添加数据

PUT /test_002/_doc/1
{
  "message": "to be or not to be"
}

通过下面的方式检索,发现结果为空

POST /test_002/_doc/_search
{
  "query": {
    "match": {
      "message": {
        "query": "to be or not to be",
        "zero_terms_query": "none"
      }
    }
  }
}

分析原因:‘to be or not tobe’分词之后的结果全都是停用词,被stop分词器全部过滤了。zero_terms_query的值为none(默认),意味着搜索不到停用词,如果值为all,相当于match_all就能检索到停用词了。

5)match的核心参数:lenient—— 忽略数据类型转换异常

# 1.id是integer类型,报错
POST /test_001/_doc/_search
{
  "query": {
    "match": {
      "id": {
        "query": "系统学"
      }
    }
  }
}
# 2.加上参数,不报错,语句正常执行
POST /test_001/_doc/_search
{
  "query": {
    "match": {
      "id": {
        "query": "系统学",
        "lenient": "true"
      }
    }
  }
}
# 3.为可转换的字符串,也不报错,语句正常执行
POST /test_001/_doc/_search
{
  "query": {
    "match": {
      "id": {
        "query": "2"
      }
    }
  }
}

分析原因:首先我们在创建test_001时,给id字段设置的类型是integer
【语句一】检索id为‘系统学’的记录,可是id为integer类型,检索条件为text/keyword,所以报错
【语句二】同样检索id为‘系统学’的记录,因为添加了忽略类型转换异常的参数,所以不会报错,但是也没有id为‘系统学’的记录,所以结果为空
【语句三】检索id为‘2’学’的记录,虽然这个‘2’也不是integer,但是它可以转换成integer,因此不会报错,而且有id为2的记录还能检索到。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值