ElasticSearch基本使用

使用场景

ElasticSearch是什么

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。       Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

ElasticSearch使用场景

ElasticSearch(后面简称ES)主要用来存储半结构化数据,实现搜索和分析功能;

ES的存储方式是JSON  主要的核心算法是倒排索引;

常用工具

Head插件(基于Node.js需手动安装):                    

访问和管理工具:http://XXXX:9100/           

在地址栏输入 http://XXXX:9200/  连接

Kibana插件:                    

命令执行工具: http://XXXX:5601

存储结构

ES、ArteryBase、GreenPlum数据存储结构对比

结构层次

字段=>文档=>类型=>索引=>分片(shard)=>节点(node)=>集群(cluster)

副本

是为了保证在某一个节点down的时候,其所拥有的分片数据不丢失 用户可以自定义分片数量、副本数量

JSON语法

查询:              

创建索引(是否存在分词器;使用动态模板)                

增加一个文档,ES中_ID问题                

定义搜索字段、搜索条件、限制返回数量                

term、match、match_phrase的使用和区别                

ES里面的聚合函数                

query与filter的使用和区别

详细样例:

1.基础查询用法
1)查询

分词
IK分词器

不进行分词的索引
PUT  /syltest
{
    "mappings": {
        "syltest": {
            "dynamic_templates": [{
                "es": {
                    "match": "*",
                    "match_mapping_type": "string",
                    "mapping": {
                        "type": "string",
                        "index": "not_analyzed"
                    }
                }
            }
            ]
        }
    }
}


GET  /syltest/_analyze?analyzer=ik_max_word
{
  "text":"es测试用例"
}

进行分词的索引
PUT  /syltest
{
    "mappings": {
        "syltest": {
            "properties": {
                "title":{
                   "type": "text",
           "analyzer": "ik_max_word"
                },
                "content":{
                   "type": "text",
           "analyzer": "ik_max_word"
                }
              
            }
        }
    }
}

动态模板
PUT  /syltest
{
	"mappings": {
		"syltest": {
		  "dynamic_templates":[{
		      "es":{
		        "match_mapping_type": "string",
            "mapping": {
              "type": "text",
              "analyzer": "ik_max_word"
            }
		      }
		    }]
		}
	}
}




动态模板,对某一字段进行分词过滤
PUT  /syltest
{
    "mappings": {
        "syltest": {
          "dynamic_templates":[
            {
              "eh":{
                "match": "content",
                "match_mapping_type": "string",
            "mapping": {
              "type": "keyword",
              "analyzer": "not_analyzed"
            }
              }
            },{
              "es":{
                "match_mapping_type": "string",
            "mapping": {
              "type": "text",
              "analyzer": "ik_max_word"
            }
              }
            }]
        }
    }
}




term语句:完全匹配,精确查找,不会对查询体进行分词

GET syltest/syltest/_search
{
  "query": {
    "term": {
      "title":  "测试"
    }
  },
  "size": 20,
  "_source":{
    "includes":[
      "title"
      ]
    ,"excludes":[]
  }
}

分词查询match和match_phrase区别:
会对查询体进行分词,match_phrase会要求查询体分词后顺序符合


GET /syltest/syltest/_search
{
  "query": {
    "match": {
      "title": "用例测试"
    }
  }
}


GET /syltest/syltest/_search
{
  "query": {
    "match_phrase": {
      "title": "用例测试"
    }
  }
}


2)聚合函数
groupBy用法
GET  /etllog/_search
{
    "aggs" : {
        "groupBy" : {
            "terms" : { "field" : "dbsource.keyword" }
        }
    }
}

count(distinct)用法(会有准确度问题)
GET  /etllog/_search
{
  "aggs": {
    "distinct": {
      "cardinality": {
        "field": "dbsource.keyword"
      }
    }
  }
}



3)过滤器
查询置于 filter 语句内不进行评分或相关度的计算,所以所有的结果都会返回一个默认评分 1 。


GET syltest/syltest/_search
{
  "filter": {
    "term": {
      "title":  "测试"
    }
  }
}


GET syltest/syltest/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "title": "测试"
        }
      }
    }
  }
}

使用query和filter查询的话,需要使用 {query:{filtered:{}}} 来包含这两个查询语法。他们的好处是,借助于filter的速度可以快速过滤出文档,然后再由query根据条件来匹配。

JAVA API

https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html

详细样例:

package com.thunisoft.test;

import org.elasticsearch.action.search.SearchAction;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.plugins.SearchPlugin;
import org.elasticsearch.search.SearchModule;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.xpack.client.PreBuiltXPackTransportClient;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;

/**
 * @ProjectName: CallAble
 * @Package: com.thunisoft.test
 * @ClassName: ESTest
 * @Author: songyulin
 * @CreateDate: 2018/8/2 15:41
 * @UpdateRemark: 更新说明
 * @Version: 1.0
 */
public class ESTest {
    static TransportClient client = null;
    static {
        Settings settings = Settings.builder()
                .put("cluster.name", "esCluster")
                .put("xpack.security.transport.ssl.enabled", false)
                .put("client.transport.ping_timeout", "120s")
                .put("indices.store.throttle.type", "none")
                .build();
        try {
            client =new PreBuiltXPackTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("172.16.11.57"),9300));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        queryMethod();
        //queryMethodSecond();
    }
    //嵌套query查询方式
    public static void queryMethod(){
        QueryBuilder query = QueryBuilders.termQuery("title", "测试");
        SearchResponse sResponse = client.prepareSearch("syltest").setTypes("syltest").setQuery(query).setSize(20)
                .execute().actionGet();
        System.out.println(sResponse);
    }
    //直接读json方式
    public static void queryMethodSecond() throws IOException {
        String jsonStr = "{\n" +
                "  \"query\": {\n" +
                "    \"term\": {\n" +
                "      \"title\":  \"测试\"\n" +
                "    }\n" +
                "  }\n" +
                "}";
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        SearchModule searchModule = new SearchModule(Settings.EMPTY, false, new ArrayList<SearchPlugin>());
        try (
                XContentParser parser = XContentFactory.xContent(XContentType.JSON)
                        .createParser( new NamedXContentRegistry(searchModule.getNamedXContents()), jsonStr))
        {
            searchSourceBuilder.parseXContent(new QueryParseContext(parser));
        }
        SearchRequestBuilder searchRequestBuilder = new SearchRequestBuilder(client, SearchAction.INSTANCE);
        SearchResponse searchResponse = searchRequestBuilder.setSource(searchSourceBuilder).setIndices("syltest")
                .execute().actionGet();
        System.out.println(searchResponse);
    }
}

POM:

<dependency>            

<groupId>org.elasticsearch</groupId>            

<artifactId>elasticsearch</artifactId>            

<version>5.6.1</version>        

</dependency>    

   

<dependency>            

<groupId>org.elasticsearch.client</groupId>            

<artifactId>transport</artifactId>            

<version>5.6.1</version>        

</dependency>    

   

<dependency>            

<groupId>org.elasticsearch.client</groupId>            

<artifactId>x-pack-transport</artifactId>            

<version>5.6.1</version>  

</dependency>

ES5新增特性

引入新的字段类型Text/Keyword 来替换 String

keyword类型的数据只能完全匹配,适合那些不需要分词的数据,对过滤、聚合非常友好, text当然就是全文检索需要分词的字段类型了。

旧索引删除机制

旧节点包含旧的索引数据时,重新启用节点会加载旧的索引数据,es5.0会在集群状态信息里面保留500个删除的索引信息,所以如果发现这个索引是已经删除过的就会自动清理,不会再重复加进来

java client API

新的基于HTTP协议的客户端对Elasticsearch的依赖解耦,没有jar包冲突,提供了集群节点自动发现、日志处理、节点请求失败自动进行请求轮询,充分发挥Elasticsearch的高可用能力,并且性能不相上下。

ES执行计划profile 

profile API提供有关搜索请求中各个组件的执行的 详细计时信息。它使用户能够深入了解如何在较低级别执行 搜索请求,以便用户可以理解为什么某些请求很慢, 并采取措施来改进它们。

Lucene执行计划Explain

GET syltest/syltest/_search
{
  "profile": true, 
  "query": {
    "term": {
      "title":  "测试"
    }
  }
} 

学习资源

学习资料

网页版“ElasticSearch权威指南”:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html

PDF版“ElasticSearch权威指南”

官方的ES使用文档:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/index.html

演示环境:head插件:http://*.*.11.57:9100;                    kibana插件: http://*.*.11.57:5601

 

 

 

 

 

 


版权声明:本文为weixin_40803329原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。