拋開原生的操作,這里我們采用spring提供的框架進(jìn)行操作吨艇,會(huì)是操作方便不少。
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();
}
}
實(shí)體類:
@Document(indexName = "dcang", type = "hot_word_es")
public class HotWordEs {
@Id
private Long id;
/**
* 搜索類型
*/
@Field(type = FieldType.String)
private SearchType searchType;
/**
* 搜索關(guān)鍵字,這里用了分詞器
*/
@Field(type = FieldType.String, analyzer = "ik_max_word", searchAnalyzer=ik_max_word")
//String 被轉(zhuǎn)成 text, auto 被轉(zhuǎn)成 keyword
private String keyword;
/**
* 搜索人ID
*/
@Field(type = FieldType.Long)
private Long memberId;
Dao:
public interface HotWordEsDao extends BaseESDao<HotWordEs, Long>, HotWordEsDaoPlus {}
DaoPlus,相當(dāng)于dao接口,如:
public interface HotWordEsDaoPlus {
/**
* 查詢熱門詞匯
*
* @param searchType 詞匯類型
* @param size 查詢個(gè)數(shù)
* @return 返回結(jié)果
*/
List<String> searchHotWordEs(SearchType searchType, Integer size);
}
基礎(chǔ)的環(huán)境搭建,我就是簡單的介紹下画切。重點(diǎn)來了,我們看接下來的實(shí)例:
搜索條件:
Paste_Image.png
Paste_Image.png
實(shí)體類 :
AssociationLotEs 記錄了拍品的出價(jià)次數(shù)和圍觀人數(shù)
LotEs: 拍品
MemberEs: 會(huì)員(拍品發(fā)布者)
//根據(jù)圍觀數(shù)和競價(jià)次數(shù)囱怕,得出分值
ScoreFunctionBuilder scoreFunctionBuilder = new ScriptScoreFunctionBuilder(new Script("return doc['observerCount'].value + doc['bidPriceCount'].value"));
//查詢條件霍弹,最大出價(jià)大于4000的拍品
RangeQueryBuilder maxAmount = rangeQuery("maxAmount").gte(4000);
FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(maxAmount, scoreFunctionBuilder)
.scoreMode(FiltersFunctionScoreQuery.ScoreMode.SUM); //函數(shù)得出的分值與原始分值相加
//關(guān)聯(lián)子文檔查詢
QueryBuilder child = QueryBuilders.hasChildQuery("association_lot_es", functionScoreQueryBuilder, ScoreMode.Total);
//必須是滿足條件的店鋪
BoolQueryBuilder parent = QueryBuilders.boolQuery();
//這里不計(jì)入分值,僅為做滿足條件的查詢
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));
//關(guān)聯(lián)父文檔查詢
HasParentQueryBuilder post_es_parent = QueryBuilders.hasParentQuery("member_es", parent, true);
//第一個(gè)查詢條件生成
BoolQueryBuilder bb2 = QueryBuilders.boolQuery();
BoolQueryBuilder queryBuilder2 = bb2.must(post_es_parent).must(child);
//為人工干預(yù)的查詢增加人氣打分娃弓,僅作為打分
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();
//賦予人工干預(yù)的拍品分值典格,并組成查詢條件
bb4.must(termQuery("artificial", true).boost(0)).should(child2);
BoolQueryBuilder bb3 = QueryBuilders.boolQuery();
//組合出完整的查詢語句
bb3.should(queryBuilder2).should(bb4);
//根據(jù)結(jié)束時(shí)間計(jì)算出相應(yīng)的分值,時(shí)間默認(rèn)分值是時(shí)間戳台丛,實(shí)際應(yīng)用中得歸一化
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));
注意事項(xiàng):
超代關(guān)系的文檔耍缴,必須在同一分片上。所以routing必須保持一致挽霉,不然查詢結(jié)果會(huì)出錯(cuò)