美文网首页
spring-data-elasticsearch 实例

spring-data-elasticsearch 实例

作者: 绝世懒人 | 来源:发表于2017-03-03 17:20 被阅读0次

    抛开原生的操作,这里我们采用spring提供的框架进行操作,会是操作方便不少。

    maven引用

        <spring-data-elasticsearch.version>2.0.6.RELEASE</spring-data-elasticsearch.version>
            
    
           <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-elasticsearch</artifactId>
                <version>${spring-data-elasticsearch.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.elasticsearch</groupId>
                        <artifactId>elasticsearch</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    

    通用类:

    public class BaseESDaoImpl<T, ID extends Serializable> extends AbstractElasticsearchRepository<T, ID> implements BaseESDao<T, ID> {
    
    public BaseESDaoImpl() {
        super();
    }
    public BaseESDaoImpl(ElasticsearchEntityInformation<T, ID> metadata, ElasticsearchOperations elasticsearchOperations) {
        super(metadata, elasticsearchOperations);
    }
    
    public BaseESDaoImpl(ElasticsearchOperations elasticsearchOperations) {
        super(elasticsearchOperations);
    }
    
    @Override
    protected String stringIdRepresentation(ID id) {
        return id.toString();
    }
    

    }

    实体类:

     @Document(indexName = "dcang", type = "hot_word_es")
      public class HotWordEs {
    
    @Id
    private Long id;
    
    /**
     * 搜索类型
     */
    @Field(type = FieldType.String)
    private SearchType searchType;
    
    /**
     * 搜索关键字,这里用了分词器
     */
     @Field(type = FieldType.String, analyzer = "ik_max_word", searchAnalyzer=ik_max_word")
    //String 被转成 text, auto 被转成 keyword
      private String keyword;
    
    /**
     * 搜索人ID
     */
    @Field(type = FieldType.Long)
    private Long memberId;
    

    Dao:

    public interface HotWordEsDao extends BaseESDao<HotWordEs, Long>, HotWordEsDaoPlus {}
    

    DaoPlus,相当于dao接口,如:

    public interface HotWordEsDaoPlus {
    /**
     * 查询热门词汇
     *
     * @param searchType 词汇类型
     * @param size       查询个数
     * @return 返回结果
     */
    List<String> searchHotWordEs(SearchType searchType, Integer size);
    }
    

    基础的环境搭建,我就是简单的介绍下。重点来了,我们看接下来的实例:
    搜索条件:

    Paste_Image.png Paste_Image.png

    实体类 :
    AssociationLotEs 记录了拍品的出价次数和围观人数
    LotEs: 拍品
    MemberEs: 会员(拍品发布者)

           //根据围观数和竞价次数,得出分值
          ScoreFunctionBuilder scoreFunctionBuilder = new ScriptScoreFunctionBuilder(new Script("return doc['observerCount'].value + doc['bidPriceCount'].value"));
         //查询条件,最大出价大于4000的拍品
         RangeQueryBuilder maxAmount = rangeQuery("maxAmount").gte(4000);
         FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(maxAmount, scoreFunctionBuilder)
        .scoreMode(FiltersFunctionScoreQuery.ScoreMode.SUM); //函数得出的分值与原始分值相加
          //关联子文档查询
          QueryBuilder child = QueryBuilders.hasChildQuery("association_lot_es", functionScoreQueryBuilder, ScoreMode.Total);
    
        //必须是满足条件的店铺
        BoolQueryBuilder parent = QueryBuilders.boolQuery();
       //这里不计入分值,仅为做满足条件的查询
       parent.must(termQuery("certification", "true").boost(0))
        .must(termQuery("dispute", "true").boost(0))
        .must(rangeQuery("shopLevel").gte(3).boost(0))
        .must(rangeQuery("shopScore").gte(4.7).boost(0));
         //关联父文档查询
          HasParentQueryBuilder post_es_parent = QueryBuilders.hasParentQuery("member_es", parent, true);
    
         //第一个查询条件生成
           BoolQueryBuilder bb2 = QueryBuilders.boolQuery();
           BoolQueryBuilder queryBuilder2 = bb2.must(post_es_parent).must(child);
    
           //为人工干预的查询增加人气打分,仅作为打分
           ScoreFunctionBuilder scoreFunctionBuilder2 = new ScriptScoreFunctionBuilder(new     Script("return doc['observerCount'].value + doc['bidPriceCount'].value"));
          FunctionScoreQueryBuilder functionScoreQueryBuilder2 =     QueryBuilders.functionScoreQuery(scoreFunctionBuilder2).scoreMode(FiltersFunctionScoreQ uery.ScoreMode.SUM);
        QueryBuilder child2 = QueryBuilders.hasChildQuery("association_lot_es", functionScoreQueryBuilder2, ScoreMode.Total);
    
         BoolQueryBuilder bb4 = QueryBuilders.boolQuery();
         //赋予人工干预的拍品分值,并组成查询条件
           bb4.must(termQuery("artificial", true).boost(0)).should(child2);
    
          BoolQueryBuilder bb3 = QueryBuilders.boolQuery();
         //组合出完整的查询语句
          bb3.should(queryBuilder2).should(bb4);
         //根据结束时间计算出相应的分值,时间默认分值是时间戳,实际应用中得归一化
        ScoreFunctionBuilder scoreFunctionBuilder3 = new ScriptScoreFunctionBuilder(new  Script("return doc['endTime'].value "));
       //查询语句
        FunctionScoreQueryBuilder functionScoreQueryBuilder3 = QueryBuilders.functionScoreQuery(bb3, scoreFunctionBuilder3)
        .boostMode(CombineFunction.SUM);//得分相加
        Page< LotEs > search = lotEsDao.search(functionScoreQueryBuilder3, new PageRequest(0, 10));
    

    注意事项:
    超代关系的文档,必须在同一分片上。所以routing必须保持一致,不然查询结果会出错

    相关文章

      网友评论

          本文标题:spring-data-elasticsearch 实例

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