Elasticsearch

文章目录

  • es安装和启动
    • 安装
    • 启动和关闭
  • IK分词器
    • 安装
    • 自定义词库
    • 分词模式
  • 索引管理
    • 创建index
    • 删除index
    • 创建type
    • 新增document
    • 修改document
    • 删除document
    • 查询document
  • DSL搜索
    • match_all查询
    • 分页查询
    • match查询
    • multi_match查询
    • bool查询
    • filter查询
    • highlight查询
  • 索引管理
    • 创建index
    • 删除index
    • 创建type
    • 新增document
    • 修改document
    • 删除document
    • 查询document
  • DSL搜索
    • match_all查询
    • 分页查询
    • match查询
    • multi_match查询
    • bool查询
    • filter查询
    • highlight查询
  • head概述
    • 下载
    • 运行
  • Kibana概述
    • 下载
    • 安装
    • 修改配置
    • 启动
  • Spring整合Elasticsearch
    • application.yml
    • config
    • 索引管理
      • 创建索引库
      • 删除索引库
      • 添加文档
      • 批量添加文档
      • 修改文档
      • 删除文档
    • DSL搜索
      • match_all查询(匹配所有)
      • 分页查询
      • match查询
    • multi_match查询
      • bool查询
      • filter查询
      • highlight查询

es安装和启动

安装

设置虚拟机的内存>1.5G【重启】
创建admin
切换admin
解压安装包【admin】
修改elasticsearch.yml、jvm.options[admin]
解决文件创建权限、内存问题[root]

启动和关闭

启动:
./elasticsearch
./elasticsearch -d

关闭:
ctrl+c

ps-ef|grep elasticsearch
kill -9 pid

IK分词器

在添加文档时会进行分词,索引中存放的就是一个一个的词(term),当你去搜索时就是拿关键字去匹配词,最终找到词关联的文档。

安装

解压IK分词器压缩包,并将解压的文件拷贝到ES安装目录的plugins下的ik(重命名)目录下,重启es

自定义词库

IKAnalyzer.cfg.xml:配置扩展词典和停用词典
main.dic:扩展词典,例如:奥利给
stopword.dic:停用词典,例如:a、an、the、的、地、得

注意:扩展词典和停用词典必须另存为UTF-8

分词模式

ik_max_word:细粒度
ik_smart:粗粒度

索引管理

创建index

PUT /java2104
{
    "settings": {
        "number_of_shards": 2,
        "number_of_replicas": 0
    }
}

注意:一台服务器时,备份分片数量设置为0

删除index

DELETE /java2104

创建type

POST /java2104/course/_mapping
{
    "properties": {
        "name":{
            "type": "text"
        },
        "description":{
            "type": "text"
        },
        "studymodel":{
            "type": "keyword"
        }
    }
}

新增document

POST /java2104/course
{
    "name":".net从入门到放弃",
    "description":".net程序员谁都不服",
    "studymodel":"201003"
}

修改document

PUT /java2104/course/2
{
    "name":"php从入门到放弃",
    "description":"php是世界上最好的语言",
    "studymodel":"201001"
}

删除document

DELETE /java2104/course/2

查询document

GET /java2104/course/1

DSL搜索

DSL(Domain Specific Language)是ES提出的基于json的搜索方式,在搜索时传入特定的json格式的数据来完成不同的搜索需求,DSL比URI搜索方式功能强大,在项目中建议使用DSL方式来完成搜索。

match_all查询

GET /java1906/course/_search
{
  "query" : { 
    "match_all" : {}
  }
}

分页查询

GET /test_index/my_type/_search
{
  "query" : { "match_all" : {} },
  "from" : 1, # 从第几条数据开始查询,从0开始计数
  "size" : 2, # 查询多少数据
  "sort" : [
    { "order_no" : "asc" }
  ]
}

match查询

query:搜索的关键字
operator:or 表示 只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。

基本使用:

GET /java1906/course/_search
{
  "query" : {
    "match" : {
      "name": {
        "query": "spring开发"
      }
    }
  }
}

operator:

GET /java1906/course/_search
{
  "query" : {
    "match" : {
      "name": {
        "query": "spring开发",
        "operator": "and"
      }
    }
  }
}

multi_match查询

matchQuery是在一个field中去匹配,multiQuery是拿关键字去多个Field中匹配。

GET /java1906/course/_search
{
  "query": {
    "multi_match": {
      "query": "开发",
      "fields": ["name","description"]
    }
  }
}

bool查询

布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。
参数:

  • must:表示必须,多个查询条件必须都满足。(通常使用must)
  • should:表示或者,多个查询条件只要有一个满足即可。
  • must_not:表示非。
GET /java1906/course/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "开发"
          }
        },
        {
          "range": {
            "price": {
              "gte": 50,
              "lte": 100
            }
          }
        }
      ]
    }
  }
}

filter查询

过滤查询。此操作实际上就是 query DSL 的补充语法。过滤的时候,不进行任何的匹配分数计算,相对于 query 来说,filter 相对效率较高。Query 要计算搜索匹配相关度分数。Query更加适合复杂的条件搜索。

不使用 filter, name和price需要计算相关度分数:

GET /java1906/course/_search
{
  "query": {
     "bool" : {
        "must":[
            {
               "match": {
                 "name": "开发"
               }
            },
            {
              "range": {# 范围, 字段的数据必须满足某范围才有结果。
                "price": {
                  "gte": 1, # 比较符号 lt gt lte gte
                  "lte": 100
                }
              }
            }
        ]
     }
  }
}

使用 filter, price不需要计算相关度分数:

GET /java1906/course/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "开发"
          }
        }
      ],
      "filter": {# 过滤,在已有的搜索结果中进行过滤,满足条件的返回。
        "range": {
          "price": {
            "gte": 1,
            "lte": 100
          }
        }
      }
    }
  }
}

highlight查询

高亮显示:高亮不是搜索条件,是显示逻辑,在搜索的时候,经常需要对搜索关键字实现高亮显示。

GET /java1906/course/_search
{
  "query": {
    "match": {
      "name": "开发"
    }
  },
  "highlight": {
      "pre_tags": [""],
      "post_tags": [""],
      "fields": {"name": {}}
  }
}

索引管理

创建index

PUT /java2104
{
    "settings": {
        "number_of_shards": 2,
        "number_of_replicas": 0
    }
}

注意:一台服务器时,备份分片数量设置为0

删除index

DELETE /java2104

创建type

POST /java2104/course/_mapping
{
    "properties": {
        "name":{
            "type": "text"
        },
        "description":{
            "type": "text"
        },
        "studymodel":{
            "type": "keyword"
        }
    }
}

新增document

POST /java2104/course
{
    "name":".net从入门到放弃",
    "description":".net程序员谁都不服",
    "studymodel":"201003"
}

修改document

PUT /java2104/course/2
{
    "name":"php从入门到放弃",
    "description":"php是世界上最好的语言",
    "studymodel":"201001"
}

删除document

DELETE /java2104/course/2

查询document

GET /java2104/course/1

DSL搜索

DSL(Domain Specific Language)是ES提出的基于json的搜索方式,在搜索时传入特定的json格式的数据来完成不同的搜索需求,DSL比URI搜索方式功能强大,在项目中建议使用DSL方式来完成搜索。

match_all查询

GET /java1906/course/_search
{
  "query" : { 
    "match_all" : {}
  }
}

分页查询

GET /test_index/my_type/_search
{
  "query" : { "match_all" : {} },
  "from" : 1, # 从第几条数据开始查询,从0开始计数
  "size" : 2, # 查询多少数据
  "sort" : [
    { "order_no" : "asc" }
  ]
}

match查询

query:搜索的关键字
operator:or 表示 只要有一个词在文档中出现则就符合条件,and表示每个词都在文档中出现则才符合条件。

基本使用:

GET /java1906/course/_search
{
  "query" : {
    "match" : {
      "name": {
        "query": "spring开发"
      }
    }
  }
}

operator:

GET /java1906/course/_search
{
  "query" : {
    "match" : {
      "name": {
        "query": "spring开发",
        "operator": "and"
      }
    }
  }
}

multi_match查询

matchQuery是在一个field中去匹配,multiQuery是拿关键字去多个Field中匹配。

GET /java1906/course/_search
{
  "query": {
    "multi_match": {
      "query": "开发",
      "fields": ["name","description"]
    }
  }
}

bool查询

布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。
参数:

  • must:表示必须,多个查询条件必须都满足。(通常使用must)
  • should:表示或者,多个查询条件只要有一个满足即可。
  • must_not:表示非。
GET /java1906/course/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "开发"
          }
        },
        {
          "range": {
            "price": {
              "gte": 50,
              "lte": 100
            }
          }
        }
      ]
    }
  }
}

filter查询

过滤查询。此操作实际上就是 query DSL 的补充语法。过滤的时候,不进行任何的匹配分数计算,相对于 query 来说,filter 相对效率较高。Query 要计算搜索匹配相关度分数。Query更加适合复杂的条件搜索。

不使用 filter, name和price需要计算相关度分数:

GET /java1906/course/_search
{
  "query": {
     "bool" : {
        "must":[
            {
               "match": {
                 "name": "开发"
               }
            },
            {
              "range": {# 范围, 字段的数据必须满足某范围才有结果。
                "price": {
                  "gte": 1, # 比较符号 lt gt lte gte
                  "lte": 100
                }
              }
            }
        ]
     }
  }
}

使用 filter, price不需要计算相关度分数:

GET /java1906/course/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "开发"
          }
        }
      ],
      "filter": {# 过滤,在已有的搜索结果中进行过滤,满足条件的返回。
        "range": {
          "price": {
            "gte": 1,
            "lte": 100
          }
        }
      }
    }
  }
}

highlight查询

高亮显示:高亮不是搜索条件,是显示逻辑,在搜索的时候,经常需要对搜索关键字实现高亮显示。

GET /java1906/course/_search
{
  "query": {
    "match": {
      "name": "开发"
    }
  },
  "highlight": {
      "pre_tags": [""],
      "post_tags": [""],
      "fields": {"name": {}}
  }
}

head概述

head插件是ES的一个可视化管理插件,用来监视ES的状态,并通过head客户端和ES服务进行交互,比如创建映射、创建索引等。从ES6.0开始,head插件支持使得node.js运行。

下载

下载地址:https://github.com/mobz/elasticsearch-head

运行

npm run start

Kibana概述

Kibana是ES提供的一个基于Node.js的基于Node.js的管理控制台, 可以很容易实现高级的数据分析和可视化,以图标的形式展现出来。
kibana可以用来编辑请求语句,方便学习操作es的语法。有时在进行编写程序,写到查询语句时,往往我会使用kibana进行书写,然后再粘贴到程序中。(不容易出错)

下载

ElasticSearch官网:https://www.elastic.co/cn/

安装

在window中安装Kibana很方便,解压即安装

修改配置

修改config/kibana.yml配置:

server.port: 5601
server.host: "0.0.0.0" #允许来自远程用户的连接
elasticsearch.url: http://192.168.204.135:9200

启动

./bin/kibana

Spring整合Elasticsearch

application.yml

spring:
  data:
    elasticsearch:
      cluster-nodes: 192.168.233.134:9200

config

@Configuration
public class ElasticsearchConfig extends ElasticsearchProperties{

	@Bean
	public RestHighLevelClient getRestHighLevelClient() {
        String[] hosts = getClusterNodes().split(",");
        HttpHost[] httpHosts = new HttpHost[hosts.length];
        for (int i = 0; i < httpHosts.length; i++) {
            String h = hosts[i];
            httpHosts[i] = new HttpHost(h.split(":")[0],
                                        Integer.parseInt(h.split(":")[1]));
        }
		return new RestHighLevelClient(RestClient.builder(httpHosts));
	}
}

索引管理

创建索引库

public class IndexWriterTest {
	@Autowired
    private RestHighLevelClient restHighLevelClient;

   //创建索引库
    @Test
    public void testCreateIndex() throws IOException {
        //创建“创建索引请求”对象,并设置索引名称
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("java1906");
        //设置索引参数
        createIndexRequest.settings("{\n" +
                "       \"number_of_shards\" : 2,\n" +
                "       \"number_of_replicas\" : 0\n" +
                "  }", XContentType.JSON);
        createIndexRequest.mapping("course", "{\r\n" + 
        		"  \"_source\": {\r\n" + 
        		"    \"excludes\":[\"description\"]\r\n" + 
        		"  }, \r\n" + 
        		" 	\"properties\": {\r\n" + 
        		"           \"name\": {\r\n" + 
        		"              \"type\": \"text\",\r\n" + 
        		"              \"analyzer\":\"ik_max_word\",\r\n" + 
        		"              \"search_analyzer\":\"ik_smart\"\r\n" + 
        		"           },\r\n" + 
        		"           \"description\": {\r\n" + 
        		"              \"type\": \"text\",\r\n" + 
        		"              \"analyzer\":\"ik_max_word\",\r\n" + 
        		"              \"search_analyzer\":\"ik_smart\"\r\n" + 
        		"           },\r\n" + 
        		"           \"studymodel\": {\r\n" + 
        		"              \"type\": \"keyword\"\r\n" + 
        		"           },\r\n" + 
        		"           \"price\": {\r\n" + 
        		"              \"type\": \"float\"\r\n" + 
        		"           },\r\n" + 
        		"           \"timestamp\": {\r\n" + 
        		"          		\"type\":   \"date\",\r\n" + 
        		"          		\"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd\"\r\n" + 
        		"        	}\r\n" + 
        		"  }\r\n" + 
        		"}", XContentType.JSON);
        //创建索引操作客户端
        IndicesClient indices = restHighLevelClient.indices();

        //创建响应对象
        CreateIndexResponse createIndexResponse = 
            indices.create(createIndexRequest,RequestOptions.DEFAULT);
        //得到响应结果
        boolean acknowledged = createIndexResponse.isAcknowledged();
        System.out.println(acknowledged);
    } 
  }

删除索引库

	//删除索引库
	@Test
	public void testDeleteIndex() throws IOException {
		//创建“删除索引请求”对象
		DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("java1906");
		//创建索引操作客户端
		IndicesClient indices = restHighLevelClient.indices();
		//创建响应对象
		DeleteIndexResponse deleteIndexResponse = 
            indices.delete(deleteIndexRequest,RequestOptions.DEFAULT);
		//得到响应结果
		boolean acknowledged = deleteIndexResponse.isAcknowledged();
		System.out.println(acknowledged);
	}

添加文档

	//添加文档
	@Test
	public void testAddDocument() throws IOException {
		//创建“索引请求”对象:索引当动词
		IndexRequest indexRequest = new IndexRequest("java1906", "course", "1");
		indexRequest.source("{\n" +
				" \"name\":\"spring cloud实战\",\n" +
				" \"description\":\"本课程主要从四个章节进行讲解: 1.微服务架构入门 " +
				"2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。\",\n" +
				" \"studymodel\":\"201001\",\n" +
				" \"price\":5.6\n" +
				"}", XContentType.JSON);
		IndexResponse indexResponse = 
            restHighLevelClient.index(indexRequest,RequestOptions.DEFAULT);
		System.out.println(indexResponse.toString());
	}

批量添加文档

@Test
public void testBulkAddDocument() throws IOException {
    BulkRequest bulkRequest = new BulkRequest();
    bulkRequest.add(new IndexRequest("java1906", "course").source("{...}",
                                                                  XContentType.JSON));
    bulkRequest.add(new IndexRequest("java1906", "course").source("{...}",
                                                                  XContentType.JSON));
    BulkResponse bulkResponse = 
                   restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
    System.out.println(bulkResponse.hasFailures());
}

修改文档

@Test
public void testUpdateDocument() throws IOException {
    UpdateRequest updateRequest = new UpdateRequest("java1906", "course", "1");
    updateRequest.doc("{\n" +
            "  \"price\":7.6\n" +
            "}", XContentType.JSON);
    UpdateResponse updateResponse = 
                   restHighLevelClient.update(updateRequest,RequestOptions.DEFAULT);
    System.out.println(updateResponse.getResult());
}

删除文档

    @Test
    public void testDelDocument() throws IOException {
        //删除索引请求对象
        DeleteRequest deleteRequest = new DeleteRequest("java1906","course","1");
        //响应对象
        DeleteResponse deleteResponse = 
            restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);
        System.out.println(deleteResponse.getResult());
    }

DSL搜索

match_all查询(匹配所有)

@SpringBootTest
@RunWith(SpringRunner.class)
public class IndexSearchTest {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    private SearchRequest searchRequest;
    private SearchResponse searchResponse;

    @Before
    public void initSearchRequest() {
        // 搜索请求对象
        searchRequest = new SearchRequest("java1906");
        searchRequest.types("course");
    }

    // 搜索type下的全部记录
    @Test
    public void testSearchAll() throws Exception {

        // 搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());

        // 设置搜索源
        searchRequest.source(searchSourceBuilder);
        // 执行搜索
        searchResponse = 
            restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);

    }

    @After
    public void displayDoc() throws ParseException {
        // 搜索匹配结果
        SearchHits hits = searchResponse.getHits();
        // 搜索总记录数
        long totalHits = hits.totalHits;
        System.out.println("共搜索到" + totalHits + "条文档");
        // 匹配的文档
        SearchHit[] searchHits = hits.getHits();
        // 日期格式化对象
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (SearchHit hit : searchHits) {
            // 文档id
            String id = hit.getId();
            System.out.println("id:" + id);
            // 源文档内容
            String source = hit.getSourceAsString();
            System.out.println(source);
        }
    }
}

分页查询

//分页查询
@Test
public void testSearchPage() throws Exception {
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(QueryBuilders.matchAllQuery());
    searchSourceBuilder.from(1);
    searchSourceBuilder.size(5);
    searchSourceBuilder.sort("price", SortOrder.ASC);

    // 设置搜索源
    searchRequest.source(searchSourceBuilder);
    // 执行搜索
    searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}

match查询

@Test
public void testMatchQuery() throws Exception {
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(QueryBuilders.matchQuery("name", "spring开
                                                       发").operator(Operator.AND));
		
    // 设置搜索源
    searchRequest.source(searchSourceBuilder);
    // 执行搜索
    searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
 }

multi_match查询

@Test
public void testMultiMatchQuery() throws Exception {
   SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
   searchSourceBuilder.query(QueryBuilders.multiMatchQuery("开发","name","description"));
   	
   // 设置搜索源
   searchRequest.source(searchSourceBuilder);
   // 执行搜索
   searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}

bool查询


    @Test
    public void testBooleanMatch() throws IOException {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //json条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("name","开发"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte("50").lte(100));
        searchSourceBuilder.query(boolQueryBuilder);

        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(
            		searchRequest, RequestOptions.DEFAULT);
    }

filter查询

@Test
public void testFilterQuery() throws IOException {
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(QueryBuilders.matchQuery("name","开发"));
    boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(10).lte(100))
    searchSourceBuilder.query(boolQueryBuilder);
    searchRequest.source(searchSourceBuilder);
    searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}

highlight查询

  @Test
  public void testHighLightQuery() throws Exception {
      SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
      searchSourceBuilder.query(QueryBuilders.matchQuery("name", "spring"));
      //设置高亮
      HighlightBuilder highlightBuilder = new HighlightBuilder();
      highlightBuilder.preTags("");
      highlightBuilder.postTags("");
      highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
      searchSourceBuilder.highlighter(highlightBuilder);

      searchRequest.source(searchSourceBuilder);
      searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
}

 @After
public void displayDoc() {
    SearchHits searchHits = searchResponse.getHits();
    long totalHits = searchHits.getTotalHits();
    System.out.println("共搜索到" + totalHits + "条文档");

    SearchHit[] hits = searchHits.getHits();
    for (int i = 0; i < hits.length; i++) {
        SearchHit hit = hits[i];
        String id = hit.getId();
        System.out.println("id:" + id);
        String source = hit.getSourceAsString();
        System.out.println(source);

        Map highlightFields = hit.getHighlightFields();
        if (highlightFields != null) {
            HighlightField highlightField = highlightFields.get("name");
            Text[] fragments = highlightField.getFragments();
            System.out.println("高亮字段:" + fragments[0].toString());
        }
    }
}

你可能感兴趣的:(elasticsearch,elasticsearch,搜索引擎,大数据)