美文网首页
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