文章目录
Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。可以帮助我们从海量数据中快速找到需要的内容。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的。
概念对比
| MySQL | Elasticsearch | 说明 |
|---|---|---|
| Table | Index | 索引(index),就是文档的集合,类似数据库的表(table) |
| Row | Document | 文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式 |
| Column | Field | 字段(Field),就是JSON文档中的字段,类似数据库中的列(Column) |
| Schema | Mapping | 映射(Mapping)是索引中文档的约束,例如字段类型约束。类似数据库的表结构 |
| SQL | DSL | DSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD |
优点对比
mapping 是对索引库中文档的约束,常见的mapping属性包括
更多mapping属性可查阅Elastic官方文档

创建索引库
【语法】
PUT /索引库名
{
"mappings": {
"properties": {
"字段名1":{
"type": "text",
"analyzer": "ik_smart"
},
"字段名2":{
"type": "object",
"properties": {
"子字段":{
"type": "keyword"
}
}
},
//....
}
}
}
【案例】

查询索引库
【语法】
GET /索引库名
【案例】
GET /why
删除索引库
【语法】
DELETE /索引库名
【案例】
DELETE /why
修改索引库
索引库只能添加新的字段,索引库一旦创建就无法修改
【案例】
PUT /索引库名/_mapping
{
properties: {
"新的字段名": {
"type": "integer"
}
}
}
【案例】

【语法】
POST /索引库名称/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
"字段3": {
"子属性1": "值3",
"子属性2": "值4"
},
//...
}
【案例】

【语法】
GET /索引库/_doc/文档id
【案例】
GET /why/_doc/1
【语法】
DELETE /索引库/_doc/文档id
【案例】
DELETE /why/_doc/1
【全量修改语法】
PUT /索引库名/_doc/文档id
{
"字段1": "值1",
"字段1": "值1",
//...
}
【增量修改语法】
POST /索引库名/_update/文档id
{
"doc": {
"字段名" :"新的值"
}
}
【案例】

两种修改方式的区别

一、导入工程和数据库
本文素材来自黑马张老师的视频
二、引入依赖
<properties>
<java.version>1.8</java.version>
<!--覆盖默认的ES版本-->
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
<!--ElasticSearch依赖-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.12.1</version>
</dependency>
</dependencies>
三、初始化JavaRestClient
private RestHighLevelClient client;
@BeforeEach //初始化RestHighLevelClient
void init(){
this.client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.140.130:9200")
));
}
@AfterEach //关闭资源
void close() throws IOException {
this.client.close();
}
创建索引库
@Test //创建索引库
void testCreateHotelIndex() throws IOException {
//1.创建Request对象
CreateIndexRequest request = new CreateIndexRequest("hotel");
//2.请求参数 source:创建索引库的DSL语句,xContentType:数据类型
request.source(MAPPINF_TEMPLATE,XContentType.JSON);
//3.发送请求,创建索引库
client.indices().create(request, RequestOptions.DEFAULT);
}
判断索引库是否存在
@Test //判断索引库是否存在
void testIsExistHotelIndex() throws IOException {
//1.创建Request对象 参数是要删除索引库的名称
GetIndexRequest request = new GetIndexRequest("hotel");
//3.发送请求,判断索引库是否存在
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println("索引库是否存在:"+exists);
}
删除索引库
@Test //删除索引库
void testDeleteHotelIndex() throws IOException {
//1.创建Request对象 参数是要删除索引库的名称
DeleteIndexRequest request = new DeleteIndexRequest("hotel");
//3.发送请求,删除索引库
client.indices().delete(request, RequestOptions.DEFAULT);
}
添加文档
@Test //添加文档
void testAddIndexDocument() throws IOException {
//在数据库查找数据
Hotel hotel = hotelService.getById(61083L);
//转化为文档类型
HotelDoc hotelDoc = new HotelDoc(hotel);
//1.创建request对象
IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
//2.准备document文档 将对象序列化成json格式的字符串
String source = JSON.toJSONString(hotelDoc);
request.source(source,XContentType.JSON);
//3.发送请求,添加文档
client.index(request,RequestOptions.DEFAULT);
}
查询文档
@Test //查找文档
void testGetIndexDocument() throws IOException{
GetRequest request = new GetRequest("hotel","61083");
GetResponse documentFields = client.get(request, RequestOptions.DEFAULT);
String json = documentFields.getSourceAsString();
//将json格式的字符串反序列化成对象
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.err.println(hotelDoc);
}
更新文档
@Test //这是局部更新文档,全量更新文档代码与添加文档相同
void testUpdateIndexDocument() throws IOException{
UpdateRequest request = new UpdateRequest("hotel","61083");
request.doc(
"price","999",
"score","50"
);
client.update(request,RequestOptions.DEFAULT);
}
删除文档
@Test //删除文档
void deleteIndexDocument() throws IOException{
DeleteRequest request = new DeleteRequest("hotel","61083");
client.delete(request,RequestOptions.DEFAULT);
}
批量导入文档
@Test //批量导入文档
void testMultipleAddIndexDocument() throws IOException{
//从数据库中批量查询数据
List<Hotel> hotels = hotelService.list();
BulkRequest request = new BulkRequest();
for (Hotel hotel : hotels) {
HotelDoc hotelDoc = new HotelDoc(hotel);
request.add(new IndexRequest("hotel")
.id(hotelDoc.getId().toString())
.source(JSON.toJSONString(hotelDoc),XContentType.JSON));
}
client.bulk(request,RequestOptions.DEFAULT);
}
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"
我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption
我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.
a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],
我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam
我正在尝试复制此GETcurl请求:curl-D--XGET-H"Authorization:BasicdGVzdEB0YXByZXNlYXJjaC5jb206NGMzMTg2Mjg4YWUyM2ZkOTY2MWNiNWRmY2NlMTkzMGU="-H"Content-Type:application/json"http://staging.example.com/api/v1/campaigns在Ruby中,通过电子邮件+apikey生成身份验证:auth="Basic"+Base64::encode64("test@example.com:4c3186288ae23fd9661c
不知何故,我似乎无法获得包含我的聚合的响应...使用curl它按预期工作:HBZUMB01$curl-XPOST"http://localhost:9200/contents/_search"-d'{"size":0,"aggs":{"sport_count":{"value_count":{"field":"dwid"}}}}'我收到回复:{"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":90,"max_score":0.0,"hits":[]},"a