ElasticSearch 实现分词全文检索 - 复合查询

elasticsearch,实现,分词,全文检索,复合,查询 · 浏览次数 : 156

小编点评

**ElasticSearch 实现分词全文检索** **简介** ElasticSearch 是一个功能强大的搜索引擎,它可以用于各种文本搜索任务,包括分词全文检索。 **分词查询** 分词查询允许您在搜索中使用多个关键字进行搜索,每个关键字都表示一个词语或分词词语。 **Restful 基本操作** **Java SpringBoot ES 索引操作ElasticSearch 实现分词全文检索** ```java @Autowired private ElasticsearchClient esClient; // 创建搜索请求 SearchRequest request = new SearchRequest("articles-index"); // 指定查询条件 request.query(QueryBuilders.matchQuery("title", "ElasticSearch")); // 执行查询 SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT); // 输出搜索结果 for (SearchHit hit : searchResponse.getHits().getHits()) { System.out.println(hit.getSource()); } ``` **Java SpringBoot ES 文档操作ElasticSearch 实现分词全文检索** ```java @Autowired private ElasticsearchClient esClient; // 获取文档的 ID String id = "12345"; // 查询文档 Document document = esClient.get(id, Document.class); // 输出文档内容 System.out.println(document.get("title")); ``` **测试数据准备ElasticSearch 实现分词全文检索** ```java // 创建一个搜索源 SearchSourceBuilder builder = new SearchSourceBuilder(); // 添加查询条件 builder.query(QueryBuilders.termQuery("title", "ElasticSearch")); // 创建搜索请求 SearchRequest request = new SearchRequest("articles-index", builder); // 执行搜索 SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT); // 输出搜索结果 for (SearchHit hit : searchResponse.getHits().getHits()) { System.out.println(hit.getSource()); } ``` **term、terms 查询** ```java // 使用 term 查询 QueryBuilders.termQuery("title", "ElasticSearch"); // 使用 terms 查询 QueryBuilders.termsQuery("title", "ElasticSearch", "Java"); **match、match_all、multimatch 查询** ```java // 使用 match 查询 QueryBuilders.matchQuery("title", "ElasticSearch"); // 使用 match_all 查询 QueryBuilders.matchAllQuery("title", "ElasticSearch", "Java"); // 使用 multimatch 查询 QueryBuilders.multimatchQuery("title", "ElasticSearch", "Java", "Python"); ``` **id、ids、prefix、fuzzy、wildcard、range、regexp 查询** ```java // 使用 id 查询 QueryBuilders.idQuery("id", "12345"); // 使用 ids 查询 QueryBuilders.idsQuery("id", "12345,56789"); // 使用 prefix 查询 QueryBuilders.prefixQuery("title", "ElasticSearch", "Elastic"); // 使用 fuzzy 查询 QueryBuilders.fuzzyQuery("title", "ElasticSearch", "Elastic", 0.5f); // 使用 wildcard 查询 QueryBuilders.wildcardQuery("title", "ElasticSearch", "Elastic*"); // 使用 range 查询 QueryBuilders.rangeQuery("price", 100, 200); // 使用 regexp 查询 QueryBuilders.regexpQuery("title", "ElasticSearch", "Elastic.*"); ``` **Scroll 深分页** ```java // 获取指定偏移量 int from = 10; // 获取指定大小的文档 SearchResponse response = esClient.search( indexName, query, from, size ); // 输出搜索结果 for (SearchHit hit : response.getHits().getHits()) { System.out.println(hit.getSource()); } ``` **总结** 分词搜索是 Elasticsearch 的一种强大的功能,允许您使用多个关键字进行文本搜索。本文提供了如何使用 Java 和 Spring Boot ES 构建和执行分词搜索的示例代码。

正文

目录

ElasticSearch 实现分词全文检索 - 概述
ElasticSearch 实现分词全文检索 - ES、Kibana、IK安装
ElasticSearch 实现分词全文检索 - Restful基本操作
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 索引操作
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 文档操作
ElasticSearch 实现分词全文检索 - 测试数据准备
ElasticSearch 实现分词全文检索 - term、terms查询
ElasticSearch 实现分词全文检索 - match、match_all、multimatch查询
ElasticSearch 实现分词全文检索 - id、ids、prefix、fuzzy、wildcard、range、regexp 查询
ElasticSearch 实现分词全文检索 - Scroll 深分页
ElasticSearch 实现分词全文检索 - delete-by-query
ElasticSearch 实现分词全文检索 - 复合查询
ElasticSearch 实现分词全文检索 - filter查询
ElasticSearch 实现分词全文检索 - 高亮查询
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 经纬度查询
ElasticSearch 实现分词全文检索 - 搜素关键字自动补全(suggest)
ElasticSearch 实现分词全文检索 - SpringBoot 完整实现 Demo 附源码

数据准备

ElasticSearch 实现分词全文检索 - 测试数据准备

bool查询

复合过滤器,将多个查询条件,以一定的逻辑组合在一起

  • must:所有的条件,用 must 组合在一起,标识 and 的意思
  • must_not: 将 must_not 中的条件,全部都不能匹配,标识 not 的意思
  • should: 所有的条件,用should组合在一起,表示 or 的意思
# 查询省份为江苏或上海
# operatorld 不是联通 !=2
# smsContent 中包括 开心 和 钞票
# bool 查询
POST /sms-logs-index/_search
{
  "query": {
    "bool": {
      "should": [
        {"term": {
          "province": {
            "value": "江苏"
          }
        }},
        {"term": {
          "province": {
            "value": "上海"
          }
        }}
      ],
      "must_not": [
        {
          "term": {
            "operatorld": {
              "value": "2"
            }
          }
        }
      ],
      "must": [
        {
          "match": {
            "smsContent": "开心"
          }
        },
        {
          "match": {
            "smsContent": "钞票"
          }
        }
      ]
    }
  }
}

JAVA

@Test
void boolQuery() throws Exception {
    String indexName = "sms-logs-index";
    RestHighLevelClient client = ESClient.getClient();

    //1. 创建SearchRequest对象
    SearchRequest request = new SearchRequest(indexName);

    //2. 指定查询条件
    SearchSourceBuilder builder = new SearchSourceBuilder();
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    boolQuery.should(QueryBuilders.termQuery("province","江苏"));
    boolQuery.should(QueryBuilders.termQuery("province","上海"));
    boolQuery.mustNot(QueryBuilders.termQuery("operatorld","2"));
    boolQuery.must(QueryBuilders.matchQuery("smsContent","开心"));
    boolQuery.must(QueryBuilders.matchQuery("smsContent","钞票"));

    builder.query(boolQuery);
    request.source(builder);

    //3. 执行查询
    SearchResponse resp = client.search(request, RequestOptions.DEFAULT);

    //4. 输出返回值
    for (SearchHit hit : resp.getHits().getHits()) {
        System.out.println(hit.getSourceAsMap());
    } 
}

boosting 查询

boosting 查询可以帮助我们去影响查询后的 score

  • positive:只有匹配上positive的查询的内容,才会被放到返回的结果中
  • negative:如果匹配上和positive并且也匹配上了negative,就可以降低这样的文档 score.
  • negative_boost:指定系数,必须小于 1.0
    关于查询时,分数是如何计算的:
  • 搜索的关键字在文档中出现的频次越高,分数就越高
  • 指定的文档内容越短,分数就越高
  • 我们在搜索时,指定的关键字也会被分词,这个被分词的内容,被分词库匹配的个数越多,分数越高
POST /sms-logs-index/_search
{
  "query": {
    "boosting": {
      "positive": {
        "match": {
          "smsContent": "人"
        }
      },
      "negative": {
        "match": {
          "smsContent": "网络"   # 如果查出来的包括 网络
        }
      },
      "negative_boost": 0.5  #将分数乘以系数 0.5 ,分数越高,排名越靠前
    }
  }
}

Java

@Test
void boostringQuery() throws Exception {
    String indexName = "sms-logs-index";
    RestHighLevelClient client = ESClient.getClient();

    //1. 创建SearchRequest对象
    SearchRequest request = new SearchRequest(indexName);

    //2. 指定查询条件
    SearchSourceBuilder builder = new SearchSourceBuilder();
    BoostingQueryBuilder boostingQuery = QueryBuilders.boostingQuery(
            QueryBuilders.matchQuery("smsContent", "人"),
            QueryBuilders.matchQuery("smsContent", "网络")
    ).negativeBoost(0.5f);


    builder.query(boostingQuery);
    request.source(builder);

    //3. 执行查询
    SearchResponse resp = client.search(request, RequestOptions.DEFAULT);

    //4. 输出返回值
    for (SearchHit hit : resp.getHits().getHits()) {
        System.out.println(hit.getSourceAsMap());
    }
}

与ElasticSearch 实现分词全文检索 - 复合查询相似的内容:

ElasticSearch 实现分词全文检索 - 复合查询

boosting 查询可以帮助我们去影响查询后的 score - positive:只有匹配上positive的查询的内容,才会被放到返回的结果中 - negative:如果匹配上和positive并且也匹配上了negative,就可以降低这样的文档 score. - negative_boost:指定系数,必须小于 1.0 关于查询时,分数是如何计算的: - 搜索的关键字在文档中出现的频次越高,

ElasticSearch 实现分词全文检索 - 概述

ES 是一个使用Java语言并且基于Lucene编写的搜索引擎框架,他提供了分布式的全文搜索功能,提供了一个统一的基于Restful风格的WEB接口,官方客户端也对多种语言都提供了相应的API。

ElasticSearch 实现分词全文检索 - ES、Kibana、IK分词器安装

先把zip下载下来。放到任意一台服务器(直接github上下载多数会失败)elasticsearch-plugin install http://172.16.0.183:8899/Java/elasticsearch-analysis-ik-7.9.3.zip

ElasticSearch 实现分词全文检索 - Restful基本操作

GET 请求: ``` http://ip:port/index: 查询索引信息 http://ip;port/index/type/doc_id: 查询指定的文档信息 ``` POST 请求: ``` http://ip;port/index/type/_search: 查询文档,可以在请求体中添加json字符串来代表查询条件 http://ip;port/index/type/doc_id/

ElasticSearch 实现分词全文检索 - Java SpringBoot ES 索引操作

//1. 准备索引的 settings Settings.Builder settings = Settings.builder() //2. 准备索引的结构 Mappings XContentBuilder mappings = JsonXContent.contentBuilder() //3. 将 Settings 和 Mappings 封装到一个Request 对象中

ElasticSearch 实现分词全文检索 - Java SpringBoot ES 文档操作

//准备一个Request对象 IndexRequest request = new IndexRequest(indexName); request.id(person.getId().toString()); //手动指定ID request.source(personJson, XContentType.JSON); //通过 Client 对象执行

ElasticSearch 实现分词全文检索 - 测试数据准备

String json = JSON.toJSONStringWithDateFormat(sms, "yyyy-MM-dd HH:mm:ss"); FastJson 将日期格式化 BulkRequest bulkRequest = new BulkRequest(); Integer idx = 1; for (String json : jsonList) {

ElasticSearch 实现分词全文检索 - term、terms查询

term 查询 term的查询是代表完全匹配,搜索之前不会对你搜索的关键字进行分词,对你的关键字去文档分词库中的去匹配内容 terms和term的查询机制是一样,都不会将指定的查询关键字进行分词,直接去分词库中匹配,找到相应文档内容。 terms是在针对一个字段包含多个值的时候使用。 term: where province = 江苏 terms: where province = 江苏 or p

ElasticSearch 实现分词全文检索 - match、match_all、multimatch查询

match查询属于高层查询,他会根据你查询的字段类型不一样,采用不同的查询方式。 - 查询的是日期或者是数值的话,他会将你基于的字符串查询内容转换为日期或者数值对待。 - 如果查询的内容是一个不能被分词的内容 (keyword) ,match查询不会对你指定的查询关键字进行分词。 - 如果查询的内容时一个可以被分词的内容 (text),match会将你指定的查询内容根据一定的方式去分词,去分词库中

ElasticSearch 实现分词全文检索 - id、ids、prefix、fuzzy、wildcard、range、regexp 查询

fuzzy查询:模糊查询,我们输入字符的大概,ES就可以 wildcard 查询:通配查询,和MySQL中的 like 差不多,可以在查询时,在字符串中指定通配符 * 和占位符? range 查询:范围查询,只针对数值类型,对某一个Field进行大于或小于的范围指定查询 regexp 查询: 正则查询,通过你编写的正则表达式去匹配内容