docker-compose搭建elasticsearch+kibana環境,以及php使用elasticsearch

1、elasticsearch的Dockerfile

增長中文搜索插件analysis-ikphp

FROM docker.elastic.co/elasticsearch/elasticsearch:7.2.0
 
ENV VERSION=7.2.0
 
# https://github.com/medcl/elasticsearch-analysis-ik/releases
ADD https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v${VERSION}/elasticsearch-analysis-ik-$VERSION.zip /tmp/
RUN /usr/share/elasticsearch/bin/elasticsearch-plugin install -b file:///tmp/elasticsearch-analysis-ik-$VERSION.zip
 
RUN rm -rf /tmp/*

 

2、編寫docker-compose.yml

version: '3'
services:
  es01:
    image: "beng/es:7.2.0"
    build: .
    container_name: es01
    restart: always
    volumes:
      - ./es01/data:/usr/share/elasticsearch/data:rw
      - ./es01/logs:/user/share/elasticsearch/logs:rw
    environment:
      - node.name=es01
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - discovery.seed_hosts=es02:9300,es03:9300
      - cluster.initial_master_nodes=es01,es02,es03
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
      - "9200:9200"
      - "9300:9300"
    networks:
      - esnet
 
  es02:
    image: "beng/es:7.2.0"
    build: .
    container_name: es02
    restart: always
    volumes:
       - ./es02/data:/usr/share/elasticsearch/data:rw
       - ./es02/logs:/user/share/elasticsearch/logs:rw
    environment:
      - node.name=es02
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - discovery.seed_hosts=es01:9300,es03:9300
      - cluster.initial_master_nodes=es01,es02,es03
    ulimits:
      memlock:
        soft: -1
        hard: -1
    networks:
      - esnet
 
  es03:
    image: "beng/es:7.2.0"
    build: .
    container_name: es03
    restart: always
    volumes:
      - ./es03/data:/usr/share/elasticsearch/data:rw
      - ./es03/logs:/user/share/elasticsearch/logs:rw
    environment:
      - node.name=es03
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - discovery.seed_hosts=es01:9300,es02:9300
      - cluster.initial_master_nodes=es01,es02,es03
    ulimits:
      memlock:
        soft: -1
        hard: -1
    networks:
      - esnet
 
  kibana:
    image: docker.elastic.co/kibana/kibana:7.2.0
    container_name: kibana
    ports:
      - 5601:5601
    volumes:
      - ./kibana/kibana.yml:/usr/share/kibana/config/kibana.yml:rw
    networks:
      - esnet
      
networks:
  esnet:

  

3、編寫kibana配置文件

看到網上不少人將elasticsearch.hosts這些參數直接配置在docker-compose文件裏設置environment裏面,html

可是我在docker-compose文件裏設置environment怎樣都沒有生效(緣由沒找到),因而直接本身寫配置文件,並將配置文件磁盤映射到容器中node

#
# ** THIS IS AN AUTO-GENERATED FILE **
#
 
# Default Kibana configuration for docker target
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://es01:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
i18n.locale: zh-CN

4、在php中使用elasticsearch

composer elasticsearch php庫地址:https://packagist.org/packages/elasticsearch/elasticsearchgit

elasticsearch php的官方文檔參考:https://www.elastic.co/guide/cn/elasticsearch/php/current/_quickstart.htmlgithub

在根目錄下引入庫docker

composer require elasticsearch/elasticsearch
use Elasticsearch\ClientBuilder; //刪除索引下的全部文檔
private function deleteAllDoc() { $client = ClientBuilder::create() ->setHosts(config('api.elasticsearch_host')) ->build(); $params = [ 'index' => 'book',
        'type' => '_doc',
        'body' => [ 'query' => [ 'bool' => [ 'must_not' => ['term' => [ 'id' => -1000 ]], ] ] ] ]; $response = $client->deleteByQuery($params); echo "delete success\n"; print_r($response); } //刪除某一個文檔
private function deleteDoc($id = 0) { $client = ClientBuilder::create() ->setHosts(config('api.elasticsearch_host')) ->build(); $params = [ 'index' => 'book',
        'type' => '_doc',
        'id' => $id ]; $response = $client->delete($params); print_r($response); } //獲取文檔
private function getDoc($id = 0) { $client = ClientBuilder::create() ->setHosts(config('api.elasticsearch_host')) ->build(); $params = [ 'index' => 'book_index',
        'type' => '_doc',
        'id' => $id ]; try { $response = $client->get($params); print_r($response['_source']); } catch (Missing404Exception $e) { echo 'not exist!'; } } //添加文檔
private function addDoc() { $client = ClientBuilder::create() ->setHosts(config('api.elasticsearch_host')) ->build(); $params = [ 'index' => 'my_index',
        'type' => '_doc',
        'id' => strval(2),
        'body' => [ 'first_name' => '關 搜鍵隔字,以英逗索用號分,書本標文籤用label字,不要段混淆',
            'age' => 18 ] ]; $response = $client->index($params); print_r($response); print "\n"; } //刪除索引
private function deleteIndex() { $client = ClientBuilder::create() ->setHosts(config('api.elasticsearch_host')) ->build(); $params = ['index' => 'book']; $response = $client->indices()->delete($params); print_r($response); } //建立索引
private function createIndex() { $client = ClientBuilder::create() ->setHosts(config('api.elasticsearch_host')) ->build(); $params = [ 'index' => 'book_index',
        'body' => [ 'settings' => [ 'number_of_shards' => 2,
                'number_of_replicas' => 1 ],
            'mappings' => [ '_source' => [ 'enabled' => true ],
                'properties' => [ 'id' => [ 'type' => 'integer', ],
                    'title' => [ 'type' => 'text',
                        //使用ik中文分詞
                        'analyzer' => 'ik_max_word' ],
                    'image' => [ 'type' => 'text' ],
                    'author' => [ 'type' => 'text',
                        'analyzer' => 'ik_max_word' ],
                    'words' => [ 'type' => 'integer' ],
                    'description' => [ 'type' => 'text',
                        'analyzer' => 'ik_max_word' ],
                    'is_vip' => [ 'type' => 'integer' ],
                    'bookstatus' => [ 'type' => 'text' ],
                    'online_status' => [ 'type' => 'integer' ],
                    'type_name' => [ 'type' => 'text' ],
                    'heat' => [ 'type' => 'integer' ],
                    'stars' => [ 'type' => 'float' ], ] ] ] ]; $response = $client->indices()->create($params); print_r($response); } //搜索書籍
public function searchBook($key, $vip = 0, $page = 1) { $size = 20; $words_size = 30; $match_num = 2; $offset = ($page - 1) * $size; $client = ClientBuilder::create() ->setHosts(config('api.elasticsearch_host')) ->build(); //插入到高亮搜索字前面的內容
    $pre_tags = ""; //插入到高亮搜索字後面的內容
    $post_tags = ""; $title_weight = 20; $author_weight = 20; $description_weight = 1; $params = [ 'index' => 'book_index',
        'type' => '_doc',
        //分頁
        "from" => $offset,
        "size" => $size,
        'body' => [ 'query' => [ 'bool' => [ //其餘必須條件,書的vip
                    'must' => ['term' => [ 'is_vip' => intval($vip) ]],
                    //其餘必須條件,書的狀態必須爲已上架
                    'must' => ['term' => [ 'online_status' => 5 ]],
                    //撞擊分數規則
                    'should' => [ 'multi_match' => [ //搜索關鍵字
                            'query' => $key,
                            //書的標題權重20,書的做者標題權重20,書簡述權重爲1
                            'fields' => ['title^'.$title_weight, 'author^'.$author_weight, 'description^'.$description_weight],
                            "type" => "cross_fields",
                            "operator" => "OR",
                            //至少匹配度30%
                            "minimum_should_match" => "30%" ] ] ] ],
            //關鍵字高亮
            'highlight' => [ //匹配包含關鍵字的高亮次數,好比有30段文本包含關鍵字,若是隻須要前面兩次的,那$match_num=2
                'number_of_fragments' => $match_num,
                //匹配包含關鍵字的高亮段落保留多少文字,好比一片文章中有30個片斷包含關鍵字, //每一個片斷保留30個文字,則$words_size=30,多餘的會忽略
                'fragment_size' => $words_size,
                'fields' => [ //高亮的字段,這裏高亮書的標題和做者以及書簡述
                    'title' => ['pre_tags' => $pre_tags, 'post_tags' => $post_tags,],
                    'author' => ['pre_tags' => $pre_tags, 'post_tags' => $post_tags,],
                    'description' => ['pre_tags' => $pre_tags, 'post_tags' => $post_tags,], ] ] ] ]; $results = $client->search($params); $hits = $results['hits']['hits']; if (empty($results['hits']['hits'])) { return []; } $books = []; //提取書信息
    foreach ($hits as $key => $value) { $book = []; $book['book_id'] = $value['_source']['id']; if (!empty($value['highlight']['title'])) { $book['title'] = $value['highlight']['title'][0]; } else { $book['title'] = $value['_source']['title']; } if (!empty($value['highlight']['author'])) { $book['author'] = $value['highlight']['author'][0]; } else { $book['author'] = $value['_source']['author']; } if (!empty($value['highlight']['description'])) { $book['description'] = $value['highlight']['description'][0]; if (!empty($value['highlight']['description'][1])) { $book['description'] = $book['description']. '...' .$value['highlight']['description'][1]; } } else { $book['description'] = $value['_source']['description']; } $book['description'] = str_replace(array( "\r\n", "\n\n", "\r", "  "), "", $book['description']); $book['bookstatus'] = $value['_source']['bookstatus']; $book['image'] = $value['_source']['image']; $book['words'] = $value['_source']['words']; $book['stars'] = $value['_source']['stars']; $book['heat'] = $value['_source']['heat']; $book['type_name'] = $value['_source']['type_name']; array_push($books, $book); } return $books; }
相關文章
相關標籤/搜索