es学习1
一、简单介绍
elasticsearch是一个基于Lucene的高扩展的分布式搜索服务器,支持开箱即用。
elasticsearch隐藏了Lucene的复杂性,对外提供Restful 接口来操作索引、搜索。
二、es和关系型数据库的几个概念的对比
数据库--->表--->行--->列
索引--->类型--->文档--->字段(映射)
三、es的使用步骤
es对外提供的http操作端口是9200
3.1 创建索引
向es服务器发送put请求,创建索库
put http://localhost:9200/索引库名称
3.2 创建映射
在索引库中每个文档都包括了一个或多个field,创建映射就是向索引库中创建field的过程
post请求创建映射
post http://localhost:9200/索引库名称/类型名称/_mapping
请求体中是映射的具体配置
{
"properties": {
"name": {
"type": "text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_smart"
},
"pic": {
"type": "text",
"index":false
},
"studymodel": {
"type": "keyword"
},
"description":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_smart"
}
}
}
3.3 创建文档
Post http://localhost:9200/索引库名称/类型名/
请求体中是文档的内容的json格式,和给索引库配置的映射一致。
3.4 查询文档
使用DSL搜索进行查询
DSL(Domain Specific Language)是ES提出的基于json的搜索方式,在搜索时传入特定的json格式的数据来完成不 同的搜索需求 。
查询地址: post http://localhost:9200/_search
在请求体中设置用DSL设置查询条件
{
"query": {
"match_all": {}
},
"_source": ["name", "studymodel"]
}
四、使用es的java客户端
es官方推荐使用高级别的restclient,Java High Level REST Client
使用方式:
对应的依赖:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.2.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.2.1</version>
</dependency>
在spring容器中配置restclient对象,这个是es java客户端的核心对象:RestHighLevelClient
@Configuration
public class ElasticConfig {
@Value("${esclient.elasticserach.hostlist}")
private String host;
/**
* 创建高级别的客户端
* @return
*/
@Bean
public RestHighLevelClient restHighLevelClient(){
//解析host配置信息
HttpHost httpHost=new HttpHost(host.split(":")[0],Integer.parseInt(host.split(":")[1]));
//创建RestHighLevelClient
return new RestHighLevelClient(RestClient.builder(httpHost));
}
}
常见方法的使用:创建索引,添加文档,查询文档
@RunWith(SpringRunner.class)
@SpringBootTest(classes = EsStudyApplication.class)
public class Test1 {
@Autowired
private RestHighLevelClient highLevelClient;
@Test
public void testCreateIndex() throws IOException {
//创建索引请求对象
CreateIndexRequest createIndexRequest=new CreateIndexRequest("index_java");
//创建索引操作客户端
IndicesClient indices = highLevelClient.indices();
//发起请求,创建索引
CreateIndexResponse createIndexResponse = indices.create(createIndexRequest);
boolean acknowledged = createIndexResponse.isAcknowledged();
System.out.println("创建结果:"+acknowledged);
}
@Test
public void testDeleteIndex() throws IOException {
//创建删除索引请求对象
DeleteIndexRequest deleteIndexRequest=new DeleteIndexRequest("index_java");
//创建索引操作客户端,发起请求
DeleteIndexResponse deleteIndexResponse = highLevelClient.indices().delete(deleteIndexRequest);
System.out.println("删除结果:"+deleteIndexResponse.isAcknowledged());
}
@Test
public void testAddDocument() throws IOException {
Map<String,String> jsonMap=new HashMap<>();
jsonMap.put("name","es");
jsonMap.put("description","这是es学习第3天");
jsonMap.put("studymodel","自学");
jsonMap.put("pic","d:/123.jpg");
//创建索引请求对象
IndexRequest indexRequest=new IndexRequest("index_java","doc");
indexRequest.id("7");//设置文档的id
indexRequest.source(jsonMap);
//请求添加索引
IndexResponse addIndexResponse = highLevelClient.index(indexRequest);
System.out.println(addIndexResponse.status());
System.out.println("索引添加结果:"+addIndexResponse.getResult());
}
/**
* 测试根据文档id查询
* @throws IOException
*/
@Test
public void testqueryDoucmentById() throws IOException {
GetRequest getRequest=new GetRequest("index_java","doc","88FLonEBUeUxCRIUGDI3");
GetResponse getResponse = highLevelClient.get(getRequest);
//是否存在的标记
System.out.println(getResponse.isExists());
//返回查询到的结果,不存在时返回null
Map<String, Object> sourceMap = getResponse.getSource();
System.out.println(sourceMap);
}
@Test
public void testUpdateDocumentById() throws IOException {
UpdateRequest updateRequest=new UpdateRequest("index_java","doc","YnxWpHEBEZO0aa-_KafP");
Map<String,String> jsonMap=new HashMap<>();
jsonMap.put("name","测试客户端更新文档2.0");
jsonMap.put("description","这是通过java客户端更新的第一篇文档");
jsonMap.put("studymodel","1");
jsonMap.put("pic","d:/123.jpg");
updateRequest.doc(jsonMap);
UpdateResponse updateResponse = highLevelClient.update(updateRequest);
System.out.println(updateResponse.status());
}
/**
* 根据文档id删除,不知道id时可以先查询出对应的文档,再根据id删除
* @throws IOException
*/
@Test
public void testdeleteDocumentById() throws IOException {
DeleteRequest deleteRequest=new DeleteRequest("index_java","doc","YXxVpHEBEZO0aa-_hacp");
DeleteResponse deleteResponse = highLevelClient.delete(deleteRequest);
System.out.println(deleteResponse.status());
}
@Test
public void testSearchAll() throws IOException {
SearchRequest searchRequest=new SearchRequest("index_java");
//设置类型
searchRequest.types("doc");
//创建查询条件
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//设置分页条件
searchSourceBuilder.from(0);
searchSourceBuilder.size(4);
//添加排序
searchSourceBuilder.sort(new FieldSortBuilder("studymodel").order(SortOrder.DESC));
searchRequest.source(searchSourceBuilder);
//执行查询
SearchResponse searchResponse = highLevelClient.search(searchRequest);
//解析结果
SearchHits hits = searchResponse.getHits();
for (SearchHit searchHit : hits.getHits()) {
String index=searchHit.getIndex();
String id=searchHit.getId();
String sourceAsString = searchHit.getSourceAsString();
System.out.println("sourceString:"+sourceAsString);
System.out.println("-------------");
}
//取出高亮字段
for (SearchHit searchHit : hits.getHits()) {
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
System.out.println(sourceAsMap);
String name = (String) sourceAsMap.get("name");
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
System.out.println(highlightFields);
if(highlightFields!=null){
HighlightField nameField = highlightFields.get("name");
if(nameField!=null){
Text[] fragments = nameField.getFragments();
StringBuffer stringBuffer = new StringBuffer();
for (Text str : fragments) {
stringBuffer.append(str.string());
}
name = stringBuffer.toString();
System.out.println(name);
}
}
}
}
/**
* term查询,搜索关键词不进行分词,直接和倒排索引匹配,如果文档中的字段进行了分词,就可能会查不到
*/
@Test
public void testTermQuery() throws IOException {
SearchRequest searchRequest=new SearchRequest("index_java");
searchRequest.types("doc");
//添加查询条件
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("name","es自学"));
searchRequest.source(searchSourceBuilder);
//进行查询
SearchResponse searchResponse = highLevelClient.search(searchRequest);
//解析查询结果;
SearchHits hits = searchResponse.getHits();
System.out.println("查询到的总记录数:"+hits.getTotalHits());
for (SearchHit searchHit : hits.getHits()) {
System.out.println(searchHit.getSourceAsString());
System.out.println("-------------");
}
}
/**
* 全文检索,先对搜索关键字进行分词,再用分词的结果依次搜索
*/
@Test
public void testMatchQuery() throws IOException {
SearchRequest searchRequest=new SearchRequest("index_java");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("name","es自学"));
//高亮显示设置
HighlightBuilder highlightBuilder=new HighlightBuilder();
highlightBuilder.preTags("<tag>");
highlightBuilder.postTags("</tag>");
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
searchSourceBuilder.highlighter(highlightBuilder);
searchRequest.source(searchSourceBuilder);
//执行搜索
SearchResponse searchResponse = highLevelClient.search(searchRequest);
SearchHits hits = searchResponse.getHits();
System.out.println(hits.getTotalHits());
for (SearchHit searchHit : hits.getHits()) {
System.out.println(searchHit.getSourceAsString());
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
System.out.println(highlightFields);
System.out.println("-------------");
}
}
/**
* 布尔查询,must表示与,should表示或
* @throws IOException
*/
@Test
@SuppressWarnings("all")
public void testBooleanMustQuery() throws IOException {
SearchRequest searchRequest=new SearchRequest("index_java");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("studymodel","自学"))
.must(QueryBuilders.matchQuery("description","2")));
searchRequest.source(searchSourceBuilder);
//执行搜索
SearchResponse searchResponse = highLevelClient.search(searchRequest);
SearchHits hits = searchResponse.getHits();
System.out.println(hits.getTotalHits());
for (SearchHit searchHit : hits.getHits()) {
System.out.println(searchHit.getSourceAsString());
System.out.println("-------------");
}
}
/**
* 测试根据一个关键字匹配多个字段,和或查询类似
*/
@Test
public void testMultiQuery() throws IOException {
SearchRequest searchRequest=new SearchRequest("index_java");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("学习","name","description"));
//设置查询结果中要显示的字段和不显示的字段
searchSourceBuilder.fetchSource(new String[]{"name"},new String[]{""});
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = highLevelClient.search(searchRequest);
SearchHits hits = searchResponse.getHits();
System.out.println(hits.getTotalHits());
for (SearchHit searchHit : hits.getHits()) {
System.out.println(searchHit.getSourceAsString());
System.out.println("-------------");
}
}
/**
* 过滤器测试,过滤器针对搜索的结果进行过滤,性能比查询要好,只能在布尔查询器上添加过滤器
*/
@Test
@SuppressWarnings("all")
public void testFilter() throws IOException {
SearchRequest searchRequest=new SearchRequest("index_java");
searchRequest.types("doc");
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("studymodel", "自学"));
//添加过滤器
boolQueryBuilder.filter(QueryBuilders.termQuery("name","1"));//过滤name含有1的记录,
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
//执行搜索
SearchResponse searchResponse = highLevelClient.search(searchRequest);
SearchHits hits = searchResponse.getHits();
System.out.println(hits.getTotalHits());
for (SearchHit searchHit : hits.getHits()) {
System.out.println(searchHit.getSourceAsString());
System.out.println("-------------");
}
}
}