美文网首页技术干货
7.ElasticSearch(SpringDataElasti

7.ElasticSearch(SpringDataElasti

作者: Vincilovfang | 来源:发表于2018-04-25 21:38 被阅读0次
        ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
    
        我们建立一个网站或应用程序,并要添加搜索功能,但是想要完成搜索工作的创建是非常困难的。我们希望搜索解决方案要运行速度快,我们希望能有一个零配置和一个完全免费的搜索模式,我们希望能够简单地使用JSON通过HTTP来索引数据,我们希望我们的搜索服务器始终可用,我们希望能够从一台开始并扩展到数百台,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案。因此我们利用Elasticsearch来解决所有这些问题及可能出现的更多其它问题。
        cluster
        代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的.
    

    核心概念:
    索引:类似于数据表
    映射:类似于建表语句 字段名称、字段类型、字段是否分词、是否存储、使用什么分词器
    文档:类似于一行一行的表记录
    文档类型:方便查询,把不同的文档类型放到一个索引里面
    1、导坐标
    elasticsearch
    spring-data-elasticsearch
    2、实体类customer添加注解
    @Entity
    @Table(name = "T_WAY_BILL")
    @Document(indexName = "vinci", type = "customer")
    public class Customer implements Serializable {
    @Id
    @GeneratedValue
    @Column(name = "C_ID")
    @org.springframework.data.annotation.Id
    @Field(index = FieldIndex.not_analyzed, store = true, type = FieldType.String)
    private Integer id;
    @Field(index = FieldIndex.analyzed, analyzer = "ik", searchAnalyzer = "ik", store = true, type = FieldType.String)
    private String name;
    }

    3、配置applicationContext-elasticsearch.xml
      3.1 加约束
      3.2 扫描dao 千万要注意:操作索引库的DAO层与操作数据库的DAO层的包要区分开来,否则会有冲突
      3.3 配置client
      3.4 配置搜索模板(Spring对ElasticSearch的封装)
        <!-- 2. 搜索DAO 扫描 -->
        <elasticsearch:repositories base-package="com.vinci.index"/>
        <!-- 3. 配置Client -->
        <elasticsearch:transport-client id="client" cluster-nodes="127.0.0.1:9300"/>
        <!-- 4. 配置搜索模板  -->
        <bean id="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
            <constructor-arg name="client" ref="client" />
        </bean> 
        
    4.查询
        //根据词条精准匹配查询
        QueryBuilder termQuery = new TermQueryBuilder("customerNum",customer.getcustomerNum());
        //根据词条模糊匹配查询
        QueryBuilder wildcardQuery = new WildcardQueryBuilder("sendAddress", "*" + customer.getSendAddress() + "*");
        //先把查询内容分词,再去索引库比对查询
        QueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder(customer.getSendAddress()).field("sendAddress").defaultOperator(Operator.AND);
            把查询内容分词,然后拿分词后的词条和索引库的词条比对
            默认Operator.OR   搜索条件中只要有一个词条和索引库匹配了,就可以查到
            设置Operator.AND  搜索条件中的所有词条都要和索引库匹配,才可以查到
        //布尔查询 ,多条件组合查询
        BoolQueryBuilder query = new BoolQueryBuilder(); 
     
        理解思路:
        要有面向对象的思想,每一个条件封装成一个对象(Hibernate的QBC查询、SpringDataJpa的条件查询)
        页面上一个参数,就是一个QueryBuilder
        条件1 a  条件2 b  条件3  c
        1)a and b and c
        BoolQueryBuilder query = new BoolQueryBuilder();
        query.must(a);
        query.must(b);
        query.must(c);    
    
        2)a or b or c
        query.should(a);
        query.should(b);
        query.should(c);  
    
        3)a and (b or c)
        BoolQueryBuilder query2 = new BoolQueryBuilder();
        query2.should(b);
        query2.should(c);
        query.must(a);
        query.must(query2);
        
        类比思考:
        select * from mytable where name = xx and  age < 20 and age > 15 and id in (...) and hobby like ""
        where语句一个大条件 Predicate
        子条件是一个具体的Predicate
            BetweenPredicate   age < 20 and age > 15
            LikePredicate      hobby like  ""
            InPredicate        id in (1,2,3)
            
            public Page<customer> findPageData(Customer customer, Pageable pageable) {
                // 判断customer 中条件是否存在
                if (StringUtils.isBlank(customer.getcustomerNum())
                        && StringUtils.isBlank(customer.getSendAddress())
                        && StringUtils.isBlank(customer.getRecAddress())
                        && StringUtils.isBlank(customer.getSendProNum())
                        && (customer.getSignStatus() == null || customer.getSignStatus() == 0)) { 
                    // 无条件查询 、查询数据库
                    return customerRepository.findAll(pageable);
                } else {
                    // 查询条件
                    // must 条件必须成立 and     
                    // must not 条件必须不成立 not
                    // should 条件可以成立 or
                    BoolQueryBuilder query = new BoolQueryBuilder(); // 布尔查询 ,多条件组合查询
                    // 向组合查询对象添加条件
                    if (StringUtils.isNotBlank(customer.getcustomerNum())) {
                        // 运单号查询
                        QueryBuilder tempQuery = new TermQueryBuilder("customerNum",
                                customer.getcustomerNum());
                        query.must(tempQuery);
                    }
                    if (StringUtils.isNoneBlank(customer.getSendAddress())) {
                        // 发货地 模糊查询
                        // 情况一: 输入"北" 是查询词条一部分, 使用模糊匹配词条查询
                        QueryBuilder wildcardQuery = new WildcardQueryBuilder(
                                "sendAddress", "*" + customer.getSendAddress() + "*");
    
                        // 情况二: 输入"北京市海淀区" 是多个词条组合,进行分词后 每个词条匹配查询
                        QueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder(customer.getSendAddress())
                        .field("sendAddress").defaultOperator(Operator.AND);
    
                        // 两种情况取or关系
                        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
                        boolQueryBuilder.should(wildcardQuery);
                        boolQueryBuilder.should(queryStringQueryBuilder);
    
                        query.must(boolQueryBuilder); 
                    }
                    if (StringUtils.isNoneBlank(customer.getRecAddress())) {
                        // 收货地 模糊查询
                        QueryBuilder wildcardQuery = new WildcardQueryBuilder(
                                "recAddress", "*" + customer.getRecAddress() + "*");  
                        query.must(wildcardQuery);
                    }
                    if (StringUtils.isNoneBlank(customer.getSendProNum())) {
                        
                        QueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder(customer.getSendProNum())
                        .field("sendProNum").defaultOperator(Operator.AND);
                        query.must(queryStringQueryBuilder);
                    }
                    if (customer.getSignStatus() != null && customer.getSignStatus() != 0) {
                        // 签收状态查询
                        QueryBuilder termQuery = new TermQueryBuilder("signStatus",
                                customer.getSignStatus());
                        query.must(termQuery);
                    }
    
                    SearchQuery searchQuery = new NativeSearchQuery(query);
                    searchQuery.setPageable(pageable); // 分页效果
                    // 有条件查询 、查询索引库
                    return customerIndexRepository.search(searchQuery);
                }
    
            }
    

    相关文章

      网友评论

        本文标题:7.ElasticSearch(SpringDataElasti

        本文链接:https://www.haomeiwen.com/subject/cekulftx.html