ElasticSearch是一個基于Lucene的搜索服務器愤估。它提供了一個分布式多用戶能力的全文搜索引擎,基于RESTful web接口肴楷。Elasticsearch是用Java開發(fā)的严拒,并作為Apache許可條款下的開放源碼發(fā)布扬绪,是當前流行的企業(yè)級搜索引擎。設計用于云計算中裤唠,能夠達到實時搜索挤牛,穩(wěn)定,可靠种蘸,快速墓赴,安裝使用方便。
我們建立一個網(wǎng)站或應用程序航瞭,并要添加搜索功能诫硕,但是想要完成搜索工作的創(chuàng)建是非常困難的。我們希望搜索解決方案要運行速度快刊侯,我們希望能有一個零配置和一個完全免費的搜索模式章办,我們希望能夠簡單地使用JSON通過HTTP來索引數(shù)據(jù),我們希望我們的搜索服務器始終可用滨彻,我們希望能夠從一臺開始并擴展到數(shù)百臺藕届,我們要實時搜索,我們要簡單的多租戶亭饵,我們希望建立一個云的解決方案休偶。因此我們利用Elasticsearch來解決所有這些問題及可能出現(xiàn)的更多其它問題。
cluster
代表一個集群辜羊,集群中有多個節(jié)點踏兜,其中有一個為主節(jié)點,這個主節(jié)點是可以通過選舉產(chǎn)生的八秃,主從節(jié)點是對于集群內(nèi)部來說的庇麦。es的一個概念就是去中心化,字面上理解就是無中心節(jié)點喜德,這是對于集群外部來說的山橄,因為從外部來看es集群,在邏輯上是個整體舍悯,你與任何一個節(jié)點的通信和與整個es集群通信是等價的.
核心概念:
索引:類似于數(shù)據(jù)表
映射:類似于建表語句 字段名稱航棱、字段類型、字段是否分詞萌衬、是否存儲饮醇、使用什么分詞器
文檔:類似于一行一行的表記錄
文檔類型:方便查詢,把不同的文檔類型放到一個索引里面
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層與操作數(shù)據(jù)庫的DAO層的包要區(qū)分開來,否則會有沖突
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.查詢
//根據(jù)詞條精準匹配查詢
QueryBuilder termQuery = new TermQueryBuilder("customerNum",customer.getcustomerNum());
//根據(jù)詞條模糊匹配查詢
QueryBuilder wildcardQuery = new WildcardQueryBuilder("sendAddress", "*" + customer.getSendAddress() + "*");
//先把查詢內(nèi)容分詞祠墅,再去索引庫比對查詢
QueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder(customer.getSendAddress()).field("sendAddress").defaultOperator(Operator.AND);
把查詢內(nèi)容分詞侮穿,然后拿分詞后的詞條和索引庫的詞條比對
默認Operator.OR 搜索條件中只要有一個詞條和索引庫匹配了,就可以查到
設置Operator.AND 搜索條件中的所有詞條都要和索引庫匹配毁嗦,才可以查到
//布爾查詢 亲茅,多條件組合查詢
BoolQueryBuilder query = new BoolQueryBuilder();
理解思路:
要有面向?qū)ο蟮乃枷耄恳粋€條件封裝成一個對象(Hibernate的QBC查詢狗准、SpringDataJpa的條件查詢)
頁面上一個參數(shù)克锣,就是一個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)) {
// 無條件查詢 、查詢數(shù)據(jù)庫
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())) {
// 發(fā)貨地 模糊查詢
// 情況一: 輸入"北" 是查詢詞條一部分袭祟, 使用模糊匹配詞條查詢
QueryBuilder wildcardQuery = new WildcardQueryBuilder(
"sendAddress", "*" + customer.getSendAddress() + "*");
// 情況二: 輸入"北京市海淀區(qū)" 是多個詞條組合,進行分詞后 每個詞條匹配查詢
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) {
// 簽收狀態(tài)查詢
QueryBuilder termQuery = new TermQueryBuilder("signStatus",
customer.getSignStatus());
query.must(termQuery);
}
SearchQuery searchQuery = new NativeSearchQuery(query);
searchQuery.setPageable(pageable); // 分頁效果
// 有條件查詢 捞附、查詢索引庫
return customerIndexRepository.search(searchQuery);
}
}