個(gè)人專題目錄](méi)(http://www.reibang.com/p/140e2a59db2c)
1. elasticsearch文檔過(guò)濾查詢結(jié)果
1.1 filter與query對(duì)比
filter
米奸,僅僅只是按照搜索條件過(guò)濾出需要的數(shù)據(jù)而已蔼啦,不計(jì)算任何相關(guān)度分?jǐn)?shù)睛藻,對(duì)相關(guān)度沒(méi)有任何影響汗侵;
query
别凤,會(huì)去計(jì)算每個(gè)document相對(duì)于搜索條件的相關(guān)度徘溢,并按照相關(guān)度進(jìn)行排序宛畦;
一般來(lái)說(shuō)具被,如果你是在進(jìn)行搜索纬纪,需要將最匹配搜索條件的數(shù)據(jù)先返回蚓再,那么用query;如果你只是要根據(jù)一些條件篩選出一部分?jǐn)?shù)據(jù)包各,不關(guān)注其排序摘仅,那么用filter;
除非是你的這些搜索條件问畅,你希望越符合這些搜索條件的document越排在前面返回娃属,那么這些搜索條件要放在query中六荒;如果你不希望一些搜索條件來(lái)影響你的document排序,那么就放在filter中即可矾端;
1.2 filter與query性能對(duì)比
filter
掏击,不需要計(jì)算相關(guān)度分?jǐn)?shù),不需要按照相關(guān)度分?jǐn)?shù)進(jìn)行排序秩铆,同時(shí)還有內(nèi)置的自動(dòng)cache最常使用filter的數(shù)據(jù)
query
砚亭,相反,要計(jì)算相關(guān)度分?jǐn)?shù)豺旬,按照分?jǐn)?shù)進(jìn)行排序钠惩,而且無(wú)法cache結(jié)果.
ElasticSearch提供了一種特殊的緩存,即過(guò)濾器緩存(filter cache)族阅,用來(lái)存儲(chǔ)過(guò)濾器的結(jié)果篓跛,被緩存的過(guò)濾器并不需要消耗過(guò)多的內(nèi)存(因?yàn)樗鼈冎淮鎯?chǔ)了哪些文檔能與過(guò)濾器相匹配的相關(guān)信息),而且可供后續(xù)所有與之相關(guān)的查詢重復(fù)使用坦刀,從而極大地提高了查詢性能愧沟。
1.3 filter
POST /book-index/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"brandName": {
"value": "飛利浦",
"boost": 1
}
}
},
{
"term": {
"categoryName": {
"value": "手機(jī)",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
}
@Override
public void filterInBoolQuery(String indexName) throws Exception {
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.filter(QueryBuilders.termQuery("brandName", "飛利浦"));
queryBuilder.filter(QueryBuilders.termQuery("categoryName", "手機(jī)"));
baseQuery.builder(indexName, queryBuilder);
}
1.4 range過(guò)濾器
range過(guò)濾器允許我們將搜索范圍限制在字段值給定的界限范圍內(nèi)。
POST /book-index/_search
{
"from": 0,
"size": 100,
"query": {
"bool": {
"must": [
{
"match": {
"title": {
"query": "三星",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"filter": [
{
"range": {
"price": {
"from": 2000,
"to": 3000,
"include_lower": true,
"include_upper": true,
"boost": 1
}
}
}
],
"must_not": [
{
"term": {
"brandName": {
"value": "諾基亞",
"boost": 1
}
}
}
],
"should": [
{
"term": {
"categoryName": {
"value": "手機(jī)",
"boost": 1
}
}
},
{
"term": {
"categoryName": {
"value": "平板電視",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
}
@Override
public void rangeQuery(String indexName, String fieldName, int from, int to) throws Exception {
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.should(QueryBuilders.termQuery("categoryName", "手機(jī)"));
queryBuilder.should(QueryBuilders.termQuery("categoryName", "平板電視"));
queryBuilder.must(QueryBuilders.matchQuery("title", "三星"));
queryBuilder.mustNot(QueryBuilders.termQuery("brandName", "諾基亞"));
queryBuilder.filter(QueryBuilders.rangeQuery(fieldName).from(from).to(to));
baseQuery.builder(indexName, queryBuilder);
}
@Test
public void testRangeCardQuery() throws Exception {
filterQuery.rangeQuery(indexName,"price",1,5);
}
1.5 exists 過(guò)濾器
exists 過(guò)濾器只選擇給定字段的文檔鲤遥。如果某字段沒(méi)有值沐寺,就不選擇。
比如我們查詢響應(yīng)時(shí)間不為空的文檔:
POST /book-index/_search
{
"query": {
"exists": {
"field": "title",
"boost": 1
}
}
}
@Override
public void existQuery(String indexName, String fieldName) throws Exception {
baseQuery.builder(indexName, QueryBuilders.existsQuery(fieldName));
}
@Test
public void testExistQuery() throws IOException {
Goods goods = new Goods();
goods.setId(1);
//goods.setTitle("new2 - 阿爾卡特 (OT-927) 炭黑 聯(lián)通3G手機(jī) 雙卡雙待");
goods.setPrice(22.32);
goods.setStock(23232);
goods.setSaleNum(32);
goods.setCreateTime(new Date());
goods.setCategoryName("平板電視");
goods.setBrandName("三星");
goods.setSpecStr("{\"電視屏幕尺寸\":\"46英寸\"}");
docService.addDoc(Constants.INDEX_NAME, objectMapper.writeValueAsString(goods), "1");
filterQuery.existQuery(Constants.INDEX_NAME, "title");
}