Elasticsearch

69 阅读3分钟

1.Elasticsearch相关概念

1. 倒排索引

在网页中,用户输入的搜索关键词很难通过简单的MySQL语句模糊查询就匹配到,倒排索引查询应运而生.通常我们把用来搜索的数据称作文档,例如一个网页、一个商品信息;对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。

倒排索引的实现原理: 首先把商品(或者网页标题)的文档内容进行分词,词条与包含这个词条的文档ID形成对应,词条具备唯一性,建立词条库; 其次对搜索内容进行分词,得到一个关键词列表,与词条库进行匹配,获得对应的文档ID; 最后,根据文档ID,去数据库中对应表中获取对应信息.

2.Elasticsearch与MySQL的概念对比

MYSQLELASTICSEARCHES描述
TableIndex索引
RowDocument文档【json】
ColumnFiled字段【域】
SchemaMapping映射【结构】
SQLDSL语句

3.实现工具

  1. Elasticsearch是由elastic公司开发的一套搜索引擎技术,它是elastic技术栈中的一部分。完整的技术栈包括:
  • Elasticsearch:用于数据存储、计算和搜索
  • Logstash/Beats:用于数据收集
  • Kibana:用于数据可视化

整套技术栈被称为ELK,经常用来做日志收集、系统监控和状态分析等等

  1. Kibana是elastic公司提供的用于操作Elasticsearch的可视化控制台。它的功能非常强大,包括:
  • 对Elasticsearch数据的搜索、展示
  • 对Elasticsearch数据的统计、聚合,并形成图形化报表、图形
  • 对Elasticsearch的集群状态监控
  • 它还提供了一个开发控制台(DevTools),在其中对Elasticsearch的Restful的API接口提供了语法提示
  1. IK分词器: Elasticsearch的关键就是倒排索引,而倒排索引依赖于对文档内容的分词,而分词则需要高效、精准的分词算法,IK分词器就是这样一个中文分词算法。

4. 基础代码实现

1.导入依赖(注意版本问题)

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

2.连接Kibana

RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
        HttpHost.create("http://192.168.150.101:9200")
));

13.png

14.png 以此页面为例,进行索引的相关操作.

3.创建索引

@Test
void testCreateIndex() throws IOException {
    // 1.创建Request对象
    CreateIndexRequest request = new CreateIndexRequest("items");
    // 2.准备请求参数
    request.source(MAPPING_TEMPLATE, XContentType.JSON);
    // 3.发送请求
    client.indices().create(request, RequestOptions.DEFAULT);
}

static final String MAPPING_TEMPLATE = "{\n" +
            "  "mappings": {\n" +
            "    "properties": {\n" +
            "      "id": {\n" +
            "        "type": "keyword"\n" +
            "      },\n" +
            "      "name":{\n" +
            "        "type": "text",\n" +
            "        "analyzer": "ik_max_word"\n" +
            "      },\n" +
            "      "price":{\n" +
            "        "type": "integer"\n" +
            "      },\n" +
            "      "stock":{\n" +
            "        "type": "integer"\n" +
            "      },\n" +
            "      "image":{\n" +
            "        "type": "keyword",\n" +
            "        "index": false\n" +
            "      },\n" +
            "      "category":{\n" +
            "        "type": "keyword"\n" +
            "      },\n" +
            "      "brand":{\n" +
            "        "type": "keyword"\n" +
            "      },\n" +
            "      "sold":{\n" +
            "        "type": "integer"\n" +
            "      },\n" +
            "      "commentCount":{\n" +
            "        "type": "integer"\n" +
            "      },\n" +
            "      "isAD":{\n" +
            "        "type": "boolean"\n" +
            "      },\n" +
            "      "updateTime":{\n" +
            "        "type": "date"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";

4.获得索引

/**
 * 获取索引库文档
 * @throws IOException
 */
@Test
public void getIndex() throws IOException {
    GetIndexRequest getIndexRequest = new GetIndexRequest(ITEM_INDEX);
    GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
    log.info("{}",getIndexResponse);
}

5.修改索引

PUT /索引库名/_mapping
{
  "properties": {
    "新字段名":{
      "type": "integer"
    }
  }
}

6.删除索引

@Test
void testDeleteIndex() throws IOException {
    // 1.创建Request对象
    DeleteIndexRequest request = new DeleteIndexRequest("items");
    // 2.发送请求
    client.indices().delete(request, RequestOptions.DEFAULT);
}

7.判断索引库是否存在

@Test
void testExistsIndex() throws IOException {
    // 1.创建Request对象
    GetIndexRequest request = new GetIndexRequest("items");
    // 2.发送请求
    boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
    // 3.输出
    System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
}