Elastic Search 의 기본 용법 과 클 러 스 터 구축

프로필
ElasticSearch 와 Solr 는 모두 Lucene 기반 검색엔진 이지 만 ElasticSearch 는 천성적으로 분포 식 을 지원 하고 Solr 는 4.0 버 전의 SolrCloud 가 분포 식 버 전 이 며 Solr 의 분포 식 지원 은 ZooKeeper 의 지원 이 필요 합 니 다.
여기에 ElasticSearch 와 Solr 의 상세 한 비교 가 있 습 니 다.http://solr-vs-elasticsearch.com/
기본 용법
Elasticsearch 클 러 스 터 는 여러 개의 색인 (indices) 을 포함 할 수 있 습 니 다. 모든 색인 은 여러 가지 유형 (types) 을 포함 할 수 있 습 니 다. 모든 유형 은 여러 개의 문서 (documents) 를 포함 하고 모든 문서 에는 여러 필드 (Fields) 가 포함 되 어 있 습 니 다. 이런 문서 형 저장 은 NoSQL 의 일종 이 라 고 할 수 있 습 니 다.
ES 는 전통 적 인 관계 형 데이터 베이스 보다 일부 개념 에 대한 이해:
Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices   -> Types  -> Documents -> Fields

클 라 이언 트 를 만 드 는 것 부터 추가, 삭제, 조회 등 기본 적 인 용법 까지:
1. 클 라 이언 트 만 들 기
public ElasticSearchService(String ipAddress, int port) {
        client = new TransportClient()
                .addTransportAddress(new InetSocketTransportAddress(ipAddress,
                        port));
    }

여 기 는 TransportClient 입 니 다.
ES 다음 두 가지 클 라 이언 트 비교:
TransportClient: 경량급 Client, Netty 스 레 드 탱크, Socket 을 사용 하여 ES 클 러 스 터 에 연결 합 니 다.그 자체 가 클 러 스 터 에 가입 하지 않 고 요청 한 처리 로 만 사 용 됩 니 다.
Node Client: 클 라 이언 트 노드 자체 도 ES 노드 입 니 다. 클 라 이언 트 에 가입 하면 다른 ElasticSearch 노드 와 같 습 니 다.이러한 Node Client 를 자주 켜 고 닫 으 면 클 러 스 터 에서 '소음' 이 발생 합 니 다.
2. Index 와 Type 정보 생 성 / 삭제
    //     
    public void createIndex() {
        client.admin().indices().create(new CreateIndexRequest(IndexName))
                .actionGet();
    }

    //       
    public void deleteIndex() {
        IndicesExistsResponse indicesExistsResponse = client.admin().indices()
                .exists(new IndicesExistsRequest(new String[] { IndexName }))
                .actionGet();
        if (indicesExistsResponse.isExists()) {
            client.admin().indices().delete(new DeleteIndexRequest(IndexName))
                    .actionGet();
        }
    }
    
    //   Index    Type
    public void deleteType(){
        client.prepareDelete().setIndex(IndexName).setType(TypeName).execute().actionGet();
    }

    //          
    public void defineIndexTypeMapping() {
        try {
            XContentBuilder mapBuilder = XContentFactory.jsonBuilder();
            mapBuilder.startObject()
            .startObject(TypeName)
                .startObject("properties")
                    .startObject(IDFieldName).field("type", "long").field("store", "yes").endObject()
                    .startObject(SeqNumFieldName).field("type", "long").field("store", "yes").endObject()
                    .startObject(IMSIFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
                    .startObject(IMEIFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
                    .startObject(DeviceIDFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
                    .startObject(OwnAreaFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
                    .startObject(TeleOperFieldName).field("type", "string").field("index", "not_analyzed").field("store", "yes").endObject()
                    .startObject(TimeFieldName).field("type", "date").field("store", "yes").endObject()
                .endObject()
            .endObject()
            .endObject();

            PutMappingRequest putMappingRequest = Requests
                    .putMappingRequest(IndexName).type(TypeName)
                    .source(mapBuilder);
            client.admin().indices().putMapping(putMappingRequest).actionGet();
        } catch (IOException e) {
            log.error(e.toString());
        }
    }

이 곳 은 특정한 Type 의 색인 맵 (Mapping) 을 사용자 정의 합 니 다. 기본 ES 는 데이터 형식의 맵 을 자동 으로 처리 합 니 다. 전체 맵 은 long 이 고 부동 소수점 은 double 이 며 문자열 은 string 이 고 시간 은 date 이 며 true 또는 false 는 boolean 입 니 다.
메모: 문자열 에 대해 ES 는 기본적으로 "analyzed" 처 리 를 합 니 다. 즉, 단 어 를 먼저 나 누고 stop words 를 제거 하 는 등 처리 한 다음 index 입 니 다.문자열 을 전체적으로 색인 할 필요 가 있다 면 이 필드 를 이렇게 설정 해 야 합 니 다: field ("index", "not analyzed").
자세 한 내용 은 참고:https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping-intro.html
3. 색인 데이터
    //       
    public void indexHotSpotDataList(List<Hotspotdata> dataList) {
        if (dataList != null) {
            int size = dataList.size();
            if (size > 0) {
                BulkRequestBuilder bulkRequest = client.prepareBulk();
                for (int i = 0; i < size; ++i) {
                    Hotspotdata data = dataList.get(i);
                    String jsonSource = getIndexDataFromHotspotData(data);
                    if (jsonSource != null) {
                        bulkRequest.add(client
                                .prepareIndex(IndexName, TypeName,
                                        data.getId().toString())
                                .setRefresh(true).setSource(jsonSource));
                    }
                }

                BulkResponse bulkResponse = bulkRequest.execute().actionGet();
                if (bulkResponse.hasFailures()) {
                    Iterator<BulkItemResponse> iter = bulkResponse.iterator();
                    while (iter.hasNext()) {
                        BulkItemResponse itemResponse = iter.next();
                        if (itemResponse.isFailed()) {
                            log.error(itemResponse.getFailureMessage());
                        }
                    }
                }
            }
        }
    }

    //     
    public boolean indexHotspotData(Hotspotdata data) {
        String jsonSource = getIndexDataFromHotspotData(data);
        if (jsonSource != null) {
            IndexRequestBuilder requestBuilder = client.prepareIndex(IndexName,
                    TypeName).setRefresh(true);
            requestBuilder.setSource(jsonSource)
                    .execute().actionGet();
            return true;
        }

        return false;
    }

    //        
    public String getIndexDataFromHotspotData(Hotspotdata data) {
        String jsonString = null;
        if (data != null) {
            try {
                XContentBuilder jsonBuilder = XContentFactory.jsonBuilder();
                jsonBuilder.startObject().field(IDFieldName, data.getId())
                        .field(SeqNumFieldName, data.getSeqNum())
                        .field(IMSIFieldName, data.getImsi())
                        .field(IMEIFieldName, data.getImei())
                        .field(DeviceIDFieldName, data.getDeviceID())
                        .field(OwnAreaFieldName, data.getOwnArea())
                        .field(TeleOperFieldName, data.getTeleOper())
                        .field(TimeFieldName, data.getCollectTime())
                        .endObject();
                jsonString = jsonBuilder.string();
            } catch (IOException e) {
                log.equals(e);
            }
        }

        return jsonString;
    }

ES 는 일괄 및 단일 데이터 인덱스 를 지원 합 니 다.
4. 조회 획득 데이터
    //       100 
    private List<Integer> getSearchData(QueryBuilder queryBuilder) {
        List<Integer> ids = new ArrayList<>();
        SearchResponse searchResponse = client.prepareSearch(IndexName)
                .setTypes(TypeName).setQuery(queryBuilder).setSize(100)
                .execute().actionGet();
        SearchHits searchHits = searchResponse.getHits();
        for (SearchHit searchHit : searchHits) {
            Integer id = (Integer) searchHit.getSource().get("id");
            ids.add(id);
        }
        return ids;
    }

    //       
    private List<Integer> getSearchDataByScrolls(QueryBuilder queryBuilder) {
        List<Integer> ids = new ArrayList<>();
        //     100000  
        SearchResponse scrollResp = client.prepareSearch(IndexName)
                .setSearchType(SearchType.SCAN).setScroll(new TimeValue(60000))
                .setQuery(queryBuilder).setSize(100000).execute().actionGet();
        while (true) {
            for (SearchHit searchHit : scrollResp.getHits().getHits()) {
                Integer id = (Integer) searchHit.getSource().get(IDFieldName);
                ids.add(id);
            }
            scrollResp = client.prepareSearchScroll(scrollResp.getScrollId())
                    .setScroll(new TimeValue(600000)).execute().actionGet();
            if (scrollResp.getHits().getHits().length == 0) {
                break;
            }
        }

        return ids;
    }

이 곳 의 Query Builder 는 조회 조건 입 니 다. ES 는 페이지 별로 조회 하여 데 이 터 를 얻 을 수 있 고 대량의 데 이 터 를 한꺼번에 얻 을 수 있 습 니 다. Scroll Search 를 사용 해 야 합 니 다.
5. 취 합 (Aggregation Facet) 조회 
    //                        <  ID,  >
    public Map<String, String> getDeviceDistributedInfo(String startTime,
            String endTime, List<String> deviceList) {

        Map<String, String> resultsMap = new HashMap<>();

        QueryBuilder deviceQueryBuilder = getDeviceQueryBuilder(deviceList);
        QueryBuilder rangeBuilder = getDateRangeQueryBuilder(startTime, endTime);
        QueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .must(deviceQueryBuilder).must(rangeBuilder);

        TermsBuilder termsBuilder = AggregationBuilders.terms("DeviceIDAgg").size(Integer.MAX_VALUE)
                .field(DeviceIDFieldName);
        SearchResponse searchResponse = client.prepareSearch(IndexName)
                .setQuery(queryBuilder).addAggregation(termsBuilder)
                .execute().actionGet();
        Terms terms = searchResponse.getAggregations().get("DeviceIDAgg");
        if (terms != null) {
            for (Terms.Bucket entry : terms.getBuckets()) {
                resultsMap.put(entry.getKey(),
                        String.valueOf(entry.getDocCount()));
            }
        }
        return resultsMap;
    }

Aggregation 조 회 는 통계 분석 과 같은 기능 을 조회 할 수 있다. 예 를 들 어 특정한 달의 데이터 분포 상황, 특정한 데이터 의 최대, 최소, 총화, 평균치 등 이다.
자세 한 내용 은 참고:https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-aggs.html
3. 클 러 스 터 설정
프로필 elasticsearch. yml
그룹 이름과 노드 이름:
#cluster.name: elasticsearch
#node.name: "Franz Kafka"
master 선거 참여 여부 와 데이터 저장 여부
#node.master: true
#node.data: true
편 수 와 던 전 수
#index.number_of_shards: 5#index.number_of_replicas: 1
master 에서 가장 적은 노드 수 를 선택 합 니 다. 이것 은 전체 클 러 스 터 노드 개수 의 절반 에 1, 즉 N / 2 + 1 로 설정 해 야 합 니 다.
#discovery.zen.minimum_master_nodes: 1
discovery ping 의 시간 초과, 네트워크 가 막 히 고 네트워크 상태 가 좋 지 않 은 경우 높 게 설정 합 니 다.
#discovery.zen.ping.timeout: 3s
분포 식 시스템 전체 클 러 스 터 노드 의 개수 N 은 홀수 입 니 다!!
4. Elasticsearch 플러그 인
1. elasticsearch - head 는 elasticsearch 의 클 러 스 터 관리 도구 입 니 다. / elasticsearch - 1.7.1 / bin / plugin -install mobz/elasticsearch-head
2. elasticsearch - sql: SQL 문법 으로 elasticsearch:. / bin / plugin 조회 -u https://github.com/NLPchina/elasticsearch-sql/releases/download/1.3.5/elasticsearch-sql-1.3.5.zip --install sql
github 주소:https://github.com/NLPchina/elasticsearch-sql
3. elasticsearch - bigdesk 는 elasticsearch 의 클 러 스 터 모니터링 도구 로 ES 클 러 스 터 의 각종 상 태 를 볼 수 있 습 니 다.
설치:. / bin / plugin -install lukas-vlcek/bigdesk
접근:http://192.103.101.203:9200/_plugin/bigdesk/,
4. elasticsearch - service wrapper 플러그 인 은 ElasticSearch 의 서비스 화 플러그 인 입 니 다.
... 에 있다https://github.com/elasticsearch/elasticsearch-servicewrapper이 플러그 인 을 다운로드 한 후 압축 을 풀 고 서비스 디 렉 터 리 를 elasticsearch 디 렉 터 리 의 bin 디 렉 터 리 에 복사 합 니 다.
그 다음 에 다음 문 구 를 실행 하여 ElasticSearch 를 설치, 시작, 정지 할 수 있 습 니 다.
sh elasticsearch install
sh elasticsearch start
sh elasticsearch stop
 
참고:
https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
http://stackoverflow.com/questions/10213009/solr-vs-elasticsearch

좋은 웹페이지 즐겨찾기