Elasticsearch初识

一、安装和配置

1.安装

elasticsearch默认不允许以root账号运行,所以创建一个用户
创建用户:useradd tracy
设置密码:passwd xxx
此时可能由于密码过于简单提示,直接再输入一次回车即可

切换用户:su - tracy
上传安装包

切回root用户,分配tracy用户权限:
chown tracy:tracy elasticsearch-6.3.0.tar.gz
chmod 755 elasticsearch-6.3.0.tar.gz

image.png

解压之后的目录:

image.png

2.配置

如果服务器内存不够,修改config目录下的jvm.options文件:

image.png

指定索引库和日志文件、设置允许所有ip访问(默认不允许远程服务器访问):

image.png

建立对应的文件夹

image.png

3.启动

image.png

启动中出现以下两个错误:

image.png

解决:
线程数不够
修改文件 vim /etc/security/limits.d/90-nproc.conf
* soft nproc 1024--->* soft nproc 4096

文件权限不足
切换回root用户,修改文件/etc/security/limits.conf
添加内容:

soft nofile 65536
hard nofile 131072
soft nproc 4096
hard nproc 4096

进程虚拟内存
vm.max_map_count:限制一个进程可以拥有的VMA(虚拟内存区域)的数量,继续修改配置文件:
vim /etc/sysctl.conf
添加内容:vm.max_map_count=655360
执行命令:sysctl -p

安装分词器到elasticsearch/plugins目录下
unzip elasticsearch-analysis-ik-6.3.0.zip -d ik-analyzer

二、客户端

Low Level Rest Client是低级别封装,提供一些基础功能,但更灵活

High Level Rest Client,是在Low Level Rest Client基础上进行的高级别封装,功能更丰富和完善,而且API会变的简单

三、Spring Data Elasticsearch

application.yml

spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: 120.111.61.110:9300

pom.xml



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.0.6.RELEASE
         
    
    com.hcx
    elasticsearch
    0.0.1-SNAPSHOT
    elasticsearch
    Demo project for Spring Boot

    
        UTF-8
        UTF-8
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter-data-elasticsearch
        
        
            org.springframework.boot
            spring-boot-starter
        

        
            org.projectlombok
            lombok
            1.18.6
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

Item:

package com.hcx.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

/**
 * Created by hongcaixia on 2020/2/27.
 */
@Data
@Document(indexName = "item",type = "docs",shards = 1,replicas = 0)
@NoArgsConstructor
@AllArgsConstructor
public class Item {
    @Id
    Long id;
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    String title; //标题
    @Field(type = FieldType.Keyword)
    String category;// 分类
    @Field(type = FieldType.Keyword)
    String brand; // 品牌
    @Field(type = FieldType.Double)
    Double price; // 价格
    @Field(type = FieldType.Keyword,index = false)
    String images; // 图片地址
}

ItemRepository:

package com.hcx.repository;

import com.hcx.pojo.Item;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.List;

/**
 * Created by hongcaixia on 2020/2/28.
 */
public interface ItemRepository extends ElasticsearchRepository{
    List findByTitle(String title);
    List findByPriceBetween(Double d1,Double d2);
}

ElasticsearchTest:

package com.hcx.elasticsearch;

import com.hcx.pojo.Item;
import com.hcx.repository.ItemRepository;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.*;

/**
 * Created by hongcaixia on 2020/2/27.
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class ElasticsearchTest {

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    private ItemRepository itemRepository;

    @Test
    public void testIndex() {
        elasticsearchTemplate.createIndex(Item.class);
        elasticsearchTemplate.putMapping(Item.class);
    }

    /**
     * 新增/更新
     */
    @Test
    public void testCreate() {
        Item item = new Item(1L, "小米10", "手机", "小米", 3999.00,
                "http:/image.myshoppingmall.com/1.jpg");
        itemRepository.save(item);
    }

    /**
     * 批量新增
     */
    @Test
    public void indexList() {
        List list = new ArrayList<>();
        list.add(new Item(2L, "坚果pro2", " 手机", "锤子", 3099.00, "http://image.myshoppingmall.com/2.jpg"));
        list.add(new Item(3L, "华为META20", " 手机", "华为", 4399.00, "http://image.myshoppingmall.com/3.jpg"));
        // 接收对象集合,实现批量新增
        itemRepository.saveAll(list);
    }

    /**
     * 删除
     */
    @Test
    public void testDelete() {
        Item item = new Item(1L, "小米10", "手机", "小米", 3999.00,
                "http:/image.myshoppingmall.com/1.jpg");
        itemRepository.delete(item);
    }

    /**
     * 根据id查找单条
     */
    @Test
    public void testFind() {
        Optional item = itemRepository.findById(1l);
        System.out.println(item.get());
    }

    /**
     * 查询多条并排序
     */
    @Test
    public void testFindAll() {
        Iterable items = itemRepository.findAll(Sort.by("price").descending());
        items.forEach(System.out::println);
    }

    /**
     * 根据某个字段查询
     */
    @Test
    public void testFindByTitle() {
        List items = itemRepository.findByTitle("手机");
        items.forEach(System.out::println);
    }

    @Test
    public void testFindByPriceBetween() {
        List items = itemRepository.findByPriceBetween(3099d, 4999d);
        items.forEach(System.out::println);
    }

    /**
     * 使用查询构建器查询
     */
    @Test
    public void testSearch() {
        //使用查询构建器工具构建查询条件
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "手机");
        Iterable items = itemRepository.search(queryBuilder);
        items.forEach(System.out::println);
    }

    /**
     * 使用自定义查询构建器
     */
    @Test
    public void testNative() {
        //构建自定义查询构建器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //添加基本的查询条件
        queryBuilder.withQuery(QueryBuilders.matchQuery("title", "手机"));
        //执行查询获取分页结果集
        Page itemPage = itemRepository.search(queryBuilder.build());
        System.out.println(itemPage.getTotalPages());
        System.out.println(itemPage.getTotalElements());
        itemPage.getContent().forEach(System.out::println);
    }

    /**
     * 分页
     */
    @Test
    public void testPage() {
        //构建自定义查询构建器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //添加基本的查询条件
        queryBuilder.withQuery(QueryBuilders.matchQuery("title", "手机"));
        //添加分页条件,页码从零开始
        queryBuilder.withPageable(PageRequest.of(0, 2));
        //执行查询获取分页结果集
        Page itemPage = itemRepository.search(queryBuilder.build());
        System.out.println(itemPage.getTotalPages());
        System.out.println(itemPage.getTotalElements());
        itemPage.getContent().forEach(System.out::println);
    }

    /**
     * 排序
     */
    @Test
    public void testSort() {
        //构建自定义查询构建器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //添加基本的查询条件
        queryBuilder.withQuery(QueryBuilders.matchQuery("title", "手机"));
        //根据价格降序
        queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC));
        //执行查询获取分页结果集
        Page itemPage = itemRepository.search(queryBuilder.build());
        System.out.println(itemPage.getTotalPages());
        System.out.println(itemPage.getTotalElements());
        itemPage.getContent().forEach(System.out::println);
    }

    @Test
    public void testAggregation() {
        //构建自定义查询构建器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //添加聚合
        queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand"));
        //添加结果集过滤,不包含任何字段
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{}, null));
        //执行聚合查询
        AggregatedPage itemPage = (AggregatedPage) itemRepository.search(queryBuilder.build());
        //解析聚合结果集,根据聚合的类型及字段类型强转 brand:字符串类型;聚合类型:词条聚合
        //通过聚合名称brandAgg 获取聚合对象
        StringTerms brandAgg = (StringTerms) itemPage.getAggregation("brandAgg");
        List buckets = brandAgg.getBuckets();
        buckets.forEach(bucket -> {
            //聚合名称
            System.out.println(bucket.getKeyAsString());
            //记录数
            System.out.println(bucket.getDocCount());
        });
    }

    @Test
    public void testSubAggregation() {
        //构建自定义查询构建器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //添加聚合
        queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand")
                .subAggregation(AggregationBuilders.avg("price_avg").field("price")));

        //添加结果集过滤,不包含任何字段
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{}, null));
        //执行聚合查询
        AggregatedPage itemPage = (AggregatedPage) itemRepository.search(queryBuilder.build());
        //解析聚合结果集,根据聚合的类型及字段类型强转 brand:字符串类型;聚合类型:词条聚合
        //通过聚合名称brandAgg 获取聚合对象
        StringTerms brandAgg = (StringTerms) itemPage.getAggregation("brandAgg");
        List buckets = brandAgg.getBuckets();
        buckets.forEach(bucket -> {
            //聚合名称
            System.out.println(bucket.getKeyAsString());
            //记录数
            System.out.println(bucket.getDocCount());
            //子聚合map集合:key:聚合名称  value:子聚合对象
            Map stringAggregationMap = bucket.getAggregations().asMap();
            InternalAvg priceAvg = (InternalAvg) stringAggregationMap.get("price_avg");
            System.out.println(priceAvg.getValue());
        });
    }
}

版权声明:
作者:Mr李
链接:https://www.techfm.club/p/14231.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>