当前位置: 首页 > news >正文

d47:Elasticsearch入门

Elasticsearch入门与JavaRestClient实践

1. Elasticsearch入门

Elasticsearch是一个高性能的搜索引擎框架,其核心是通过倒排索引来实现高效的搜索功能。倒排索引的工作原理如下:

将文档(数据)进行分词,基于词条创建索引,通过查询词条来获得文档ID。以下是倒排索引的示意图:

文档1: 小米手机
文档2: 华为手机
文档3: 华为小米充电器
文档4: 小米手环
原始数据
分词处理
生成倒排索引
词条: 小米
文档ID: 1,3,4
词条: 手机
文档ID: 1,2
词条: 华为
文档ID: 2,3
词条: 充电器
文档ID: 3
词条: 手环
文档ID: 4
用户搜索: 华为手机
搜索词分词
得到词条: 华为, 手机
在倒排索引中查找
华为 -> 文档2,3
手机 -> 文档1,2
取交集: 文档2
返回文档2: 华为手机

IK分词器

IK分词器是处理中文语义的分词器,可以通过RESTful风格的请求来测试分词器:

POST /_analyze
{"analyzer": "ik_smart","text": "你好"
}

IK分词器有两种模式:

  • ik_smart:智能切分,粗粒度
  • ik_max_word:最细切分,细粒度

可以通过配置config目录的IKAnalyzer.cfg.xml文件来拓展分词器词库中的词条。

2. 基本概念

Elasticsearch与MySQL的对比:

MySQL 概念/术语Elasticsearch 概念/术语说明
Table(表)Index(索引)索引是文档的集合,类似数据库的表。
Row(行)Document(文档)文档是一条条的数据,类似数据库的行,文档为JSON格式。
Column(列)Field(字段)字段是JSON文档中的字段,类似数据库的列。
Schema(表结构)Mapping(映射)映射是索引中文档的约束,例如字段类型约束,类似数据库的表结构。
SQLDSLDSL是Elasticsearch提供的JSON风格的请求语句,用于定义搜索条件。

Mapping映射

Mapping将实体映射为索引库的文档约束,常见的Mapping属性如下:

属性名作用常用取值示例
type字段数据类型字符串:text(可分词)、keyword(精确值)
数值:longintegerdoublefloat
布尔:boolean
日期:date
对象:object
index是否创建倒排索引true(默认)、false
analyzer指定分词器如:ik_max_wordik_smart
properties定义子字段(object类型)例如:name.firstNamename.lastName

例如,定义一个Book类的Mapping:

PUT /book
{"mappings": {"properties": {"id": {"type": "long"},"title": {"type": "text","analyzer": "ik_max_word"},"author": {"type": "text","analyzer": "ik_max_word"},"isbn": {"type": "keyword"},"price": {"type": "double"},"onSale": {"type": "boolean"},"publishDate": {"type": "date"}}}
}

3. JavaRestClient

引入依赖

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

与Elasticsearch连接

@BeforeEach
public void init(){client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.142.130", 9200, "http")));
}@AfterEach
public void destroy(){try {client.close();} catch (Exception e) {e.printStackTrace();}
}

4. 索引库与文档操作

索引库操作

功能请求方式请求路径请求参数说明
查询用户GET/users/{id}路径参数:用户ID
新增用户POST/users请求体:JSON格式用户对象
修改用户PUT/users/{id}路径参数:用户ID + JSON格式用户对象
删除用户DELETE/users/{id}路径参数:用户ID
创建索引库
PUT /items
{"mappings": {"properties": {......}}
}

对应到JavaRestClient的操作:

@Test
void testCreateHotelIndex() throws IOException {// 创建请求CreateIndexRequest request = new CreateIndexRequest("items");// 设置参数request.source(MAPPING_TEMPLATE, XContentType.JSON);// 发起请求client.indices().create(request, RequestOptions.DEFAULT);
}
获取和删除索引
@Test
void testGetHotelIndex() throws IOException {GetIndexRequest request = new GetIndexRequest("items");GetIndexResponse exists = client.indices().get(request, RequestOptions.DEFAULT);System.out.println(exists);
}@Test
void testDeleteHotelIndex() throws IOException {DeleteIndexRequest request = new DeleteIndexRequest("items");client.indices().delete(request, RequestOptions.DEFAULT);
}

文档操作

插入一条数据
@Test
void testIndexDocument() throws IOException {// 准备数据Item item = itemService.getById(317578L);ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);// 创建请求IndexRequest request = new IndexRequest("items").id(itemDoc.getId());// 请求参数request.source(JSONUtil.toJsonStr(itemDoc),XContentType.JSON);// 发送请求client.index(request, RequestOptions.DEFAULT);
}
获取数据
@Test
void testGetDocument() throws IOException {// 创建请求GetRequest request = new GetRequest("items", "317578");// 发送请求GetResponse response = client.get(request, RequestOptions.DEFAULT);// 获取数据String json = response.getSourceAsString();// 转换成对象ItemDoc itemDoc = JSONUtil.toBean(json, ItemDoc.class);System.out.println(itemDoc);
}
删除数据
@Test
void testDeleteDocument() throws IOException {DeleteRequest request = new DeleteRequest("items", "317578");client.delete(request, RequestOptions.DEFAULT);
}
文档更新

Elasticsearch的文档更新分为全量和增量两种方式:

  • 全量更新:直接替换掉整个旧文档

    PUT /索引库/_doc/文档id
    {"字段名":"值"......//必须包含所有的完整字段
    }
    
  • 增量更新:处理部分数据

    POST /索引库/_update/文档id
    {"doc":{"字段名":"newValue"}
    }
    

对应到JavaRestClient的操作:

@Test
void testUpdateDocument() throws IOException {UpdateRequest request = new UpdateRequest("items", "317578");request.doc("price", 9999);client.update(request, RequestOptions.DEFAULT);
}
批处理

一次性进行多条文档操作:

@Test
void testBulkDoc() throws IOException {int pageNo = 1;int pageSize = 500;while ( true){// 准备请求参数Page<Item> page = itemService.lambdaQuery().eq(Item::getStatus, 1).page(Page.of(pageNo, pageSize));List<Item> records = page.getRecords();if(records == null || records.isEmpty()){return;}BulkRequest request = new BulkRequest();for(Item item : records){ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);request.add(new IndexRequest("items").source(JSONUtil.toJsonStr(itemDoc),XContentType.JSON));}client.bulk(request, RequestOptions.DEFAULT);pageNo++;}
}

查询

在进行查询时,获取的response结构大致如下:

{"took" : 109,"timed_out" : false,"_shards" : {"total" : 6,"successful" : 6,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 10000,"relation" : "gte"},"max_score" : 1.0,"hits" : [{"_index" : ".kibana-event-log-7.12.1-000001","_type" : "_doc","_id" : "pUdzJJoBn6OMEyyxh_b6","_score" : 1.0,"_source" : {"@timestamp" : "2025-10-27T06:54:56.044Z","event" : {"provider" : "eventLog","action" : "starting"},"message" : "eventLog starting","ecs" : {"version" : "1.6.0"},"kibana" : {"server_uuid" : "d2a0f545-6cd0-43cd-ae8e-372cfd963bf6"}}}]}
}

要获取真正的数据部分,需要解析其层级:

private static void extractedResponse(SearchResponse response) {// 解析结果SearchHits hits = response.getHits();Long total = hits.getTotalHits().value;SearchHit[] items = hits.getHits();for(SearchHit item : items){String json = item.getSourceAsString();ItemDoc itemDoc = JSONUtil.toBean(json, ItemDoc.class);System.out.println(itemDoc);}
}

条件查询

Elasticsearch的条件查询支持多种子句,如下表所示:

子句名作用描述类比逻辑是否参与算分
must必须匹配与 AND
should选择性匹配(可配置最少匹配数)或 OR
must_not必须不匹配非 NOT
filter必须匹配——

例如,使用mustfilter进行查询:

@Test
void testMatchQuery() throws IOException {SearchRequest request = new SearchRequest("items");request.source().query(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("name", "小米")).filter(QueryBuilders.termQuery("category", "手机")).filter(QueryBuilders.rangeQuery("price").lte(20000).gte(1000)));SearchResponse response = client.search(request, RequestOptions.DEFAULT);extractedResponse(response);
}

排序与分页

Elasticsearch支持排序和分页操作,示例如下:

@Test
void testPageQuery() throws IOException {int  pageNo = 1;int pageSize = 5;SearchRequest request = new SearchRequest("items");request.source().query(QueryBuilders.matchAllQuery()).from((pageNo - 1) * pageSize).size(pageSize).sort("price", SortOrder.ASC).sort("sold", SortOrder.DESC);SearchResponse response = client.search(request, RequestOptions.DEFAULT);extractedResponse(response);
}
```v
http://www.dtcms.com/a/601663.html

相关文章:

  • 李宏毅机器学习笔记
  • 惠州专业网站制作公司wordpress 图片 本地
  • 毕业设计如何用dw做网站wordpress移动顶部导航菜单
  • 安科瑞Acrel-2000MG 储能能量管理系统是什么?什么场景需要用到?
  • 政策加码:中小学人工智能教育新图景
  • 全域释放活力,增长质效兼收——2025年“双11”大促第一周期观察
  • 上海华东建设发展设计有限公司网站网址域名ip
  • 平邑网站制作在线做头像的网站有哪些
  • 沈阳工务建设集团网站淘客cms建站系统
  • 深度学习_神经网络中最常用的学习率优化算法
  • INT301 Bio-computation 生物计算(神经网络)Pt.7 时间序列预测和Elman网络
  • 为什么“随机变量”是个函数?为什么“函数相加”会产生高斯分布?
  • 基于 Tuya.AI 开源的大模型构建智能聊天机器人
  • dw怎么切片做网站宁波正规网站建设使用方法
  • 软件网站建设基本流程哈尔滨建筑专业网站
  • 每日算法刷题Day85:11.12:leetcode 动态规划6道题,用时1h40min
  • Citadel SDE 面试复盘:直面硬核算法与思维挑战的双重压力
  • 【Vue 功能总结】Vue 登录功能实现:从校验到 Token 存储
  • 网站的域名在哪里看怎么查询公司的营业执照
  • 浏网站建设补贴农村服务建设有限公司网站
  • 自然语言处理(NLP)算法原理与实现--Part 1
  • 不止于 “看”:VR 地震模拟平台的防灾科普新表达
  • 临沂网站建设团队wordpress修改固定链接重定向
  • 查看iOS App实时日志的正确方式,多工具协同打造高效调试与问题定位体系(2025最新指南)
  • 怎么用手机做抖音上最火的表白网站网站制作公司哪家好一点
  • 深圳市顺建建设工程有限公司网站html5微网站demo
  • 一个空间安装多个织梦网站系统网站建设学习网站
  • windows 安装mysql(多个版本同时安装)
  • 传媒网站建设公司wordpress建站教程简书
  • 校园网站设计代码wordpress左侧菜单