Elasticsearch Query DSL之全文檢索(Full text queries)

本節(jié)將詳細介紹DSL全文搜索。
全文查詢包括如下幾種模式:

  1. match query
    標(biāo)準(zhǔn)的全文檢索模式,包含模糊匹配、前綴或近似匹配等。
  2. match_phrase query
    與match query類似储玫,但只是用來精確匹配的短語。
  3. match_phrase_prefix query
    與match_phrase查詢類似萤皂,但是在最后一個單詞上執(zhí)行通配符搜索撒穷。
  4. multi_match query
    支持多字段的match query。
  5. common terms query
    相比match query裆熙,消除停用詞與高頻詞對相關(guān)度的影響端礼。
  6. query_string query
    查詢字符串方式
  7. simple_query_string query
    簡單查詢字符串方式

1、match query詳解

1.1 match query使用示例與基本工作原理

全文索引查詢入录,這意外著首先會對待查字符串(查詢條件)進行分詞蛤奥,然后再去匹配,返回結(jié)果中會待上本次匹配的關(guān)聯(lián)度分數(shù)僚稿。
例如存在這樣一條數(shù)據(jù):

"_source":{
             "post_date":"2009-11-16T14:12:12",
              "message":"trying out Elasticsearch",
               "user":"dingw2"
      }

使用如下查詢條件:

"query": {
             "match" : {
                "message" : "this out Elasticsearch"
            }
        }

其JAVA代碼對應(yīng):

SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery("message", "this out elasticsearch"));

其大體步驟如下:
首先對this out Elasticsearch分詞凡桥,最終返回結(jié)果為 this、out蚀同、Elasticsearch缅刽,然后分別去庫中進行匹配,默認只要一個匹配蠢络,就認為匹配衰猛,但會加入一個匹配程度(關(guān)聯(lián)度),用scoce分數(shù)表示刹孔。

1.2 match query常用參數(shù)詳解

  • operator(操作類型)
    可選值為:Operator.OR 和 Operator.AND啡省。表示對查詢字符串分詞后,返回的詞根列表,OR只需一個滿足及認為匹配卦睹,而AND則需要全部詞根都能匹配畦戒,默認值為:Operator.OR。
  • minimum_should_match 最少需要匹配個數(shù)分预。
    在操作類型為Operator.OR時生效兢交,指明分詞后的詞根,至少minimum_should_match 個詞根匹配笼痹,則命中。
"match" : {
            "message" : "this out Elasticsearch"酪穿,
            “minimum_should_match ”:“3”
}

此時由于this詞根并不在原始數(shù)據(jù)"trying out Elasticsearch"中凳干,又要求必須匹配的詞根個數(shù)為3,故本次查詢被济,無法命中救赐。minimum_should_match 可選值如下:

Type Example Description
Integer 3 直接數(shù)字,不考慮查詢字符串分詞后的個數(shù)只磷。如果分詞的個數(shù)小于3個经磅,則無法匹配到任何條目。
Negative integer -2 負數(shù)表示最多不允許不匹配的個數(shù)钮追。也就是需要匹配的個數(shù)為(total-2)预厌。
Negative percentage -25% 百分比,表示需要匹配的詞根占總數(shù)的百分比元媚。
Percentage 75% 允許不匹配的個數(shù)占總數(shù)的百分比轧叽。
Combination 3<90% 如果查詢字符串分詞的個數(shù)小于等于3(前面的整數(shù)),則只要全部匹配則返回刊棕,如果分詞的個數(shù)大于3個炭晒,則只要90%的匹配即可。
Multiple combinations 2<-25% 9<-3 支持多條件表達式甥角,中間用空格分開网严。該表達式的意義如下:1、如果分詞的個數(shù)小于等于2嗤无,則必須全部匹配震束;如果大于2小于9,則除了25%(注意負號)之外都需要滿足翁巍。2驴一、如果大于9個,則只允許其中3個不滿足灶壶。
  • analyzer
    設(shè)置分詞器肝断,默認使用字段映射中定義的分詞器或elasticsearch默認的分詞器。
  • lenient
    是否忽略由于數(shù)據(jù)類型不匹配引起的異常,默認為false胸懈。例如嘗試用文本查詢字符串查詢數(shù)值字段担扑,默認會拋出錯誤。
  • fuzziness
    模糊匹配趣钱。
  • zero_terms_query
    默認情況下涌献,如果分詞器會過濾查詢字句中的停用詞,可能會造成查詢字符串分詞后變成空字符串首有,此時默認的行為是無法匹配到任何文檔燕垃,如果想改變該默認情況,可以設(shè)置zero_terms_query=all井联,類似于match_all,默認值為none卜壕。
  • cutoff_frequency
    match查詢支持cutoff_frequency,允許指定絕對或相對的文檔頻率:
    • OR:高頻單詞被放入“或許有”的類別烙常,僅在至少有一個低頻(低于cutoff_frequency)單詞滿足條
      件時才積分轴捎;
    • AND:高頻單詞被放入“或許有”的類別,僅在所有低頻(低于cutoff_frequency)單詞滿足條件時才積分蚕脏。該查詢允許在運行時動態(tài)處理停用詞而不需要使用停用詞文件侦副。它阻止了對高頻短語(停用詞)的評分/迭代,并且只在更重要/更低頻率的短語與文檔匹配時才會考慮這些文檔驼鞭。然而秦驯,如果所有查詢條件都高于給定的cutoff_frequency,則查詢將自動轉(zhuǎn)換為純連接(and)查詢终议,以確被憬撸快速執(zhí)行。
      cutoff_frequency取值是相對于文檔的總數(shù)的小數(shù)[0..1)穴张,也可以是絕對值[1, +∞)细燎。
  • Synonyms(同義詞)
    可在分詞器中定義同義詞,具體同義詞將在后續(xù)章節(jié)中會單獨介紹皂甘。

1.3 match query示例

public static void testMatchQuery() {
        RestHighLevelClient client = EsClient.getClient();
        try {
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("twitter");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(
                    QueryBuilders.matchQuery("message", "is out Elasticsearch")
                        .zeroTermsQuery(ZeroTermsQuery.ALL)
                        .operator(Operator.OR)
                        .minimumShouldMatch("4<90%")
                    ).sort(new FieldSortBuilder("post_date").order(SortOrder.DESC))
                     .docValueField("post_date", "epoch_millis");
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(result);
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            EsClient.close(client);
        }
    }

2玻驻、match_phrase query

與match query類似,但只是用來精確匹配的短語偿枕。
其主要工作流程:首先璧瞬,Elasearch(lucene)會使用分詞器對全文本進行分詞(返回一個一個的詞根(順序排列)),然后同樣使用分詞器對查詢字符串進行分析渐夸,返回一個一個的詞根(順序性)嗤锉。如果能在全字段中能夠精確找到與查詢字符串通用的詞根序列,則認為匹配墓塌,否則認為不匹配瘟忱。

舉例如下:
如果原文字段message:"quick brown fox test we will like to you",則使用標(biāo)準(zhǔn)分詞器(analyzer=standard)返回的結(jié)果如下:

curl -X GET "192.168.1.10:9200/_analyze" -H 'Content-Type: application/json' -d'
{
  "tokenizer" : "standard",
  "text" : "quick brown fox test we will like to you",
  "attributes" : ["keyword"] 
}'

得出如下結(jié)果:

{
    "tokens":[
        {
            "token":"quick",
            "start_offset":0,
            "end_offset":5,
            "type":"<ALPHANUM>",
            "position":0
        },
        {
            "token":"brown",
            "start_offset":6,
            "end_offset":11,
            "type":"<ALPHANUM>",
            "position":1
        },
        {
            "token":"fox",
            "start_offset":12,
            "end_offset":15,
            "type":"<ALPHANUM>",
            "position":2
        },
        {
            "token":"test",
            "start_offset":16,
            "end_offset":20,
            "type":"<ALPHANUM>",
            "position":3
        },
        {
            "token":"we",
            "start_offset":21,
            "end_offset":23,
            "type":"<ALPHANUM>",
            "position":4
        },
        {
            "token":"will",
            "start_offset":24,
            "end_offset":28,
            "type":"<ALPHANUM>",
            "position":5
        },
        {
            "token":"like",
            "start_offset":29,
            "end_offset":33,
            "type":"<ALPHANUM>",
            "position":6
        },
        {
            "token":"to",
            "start_offset":34,
            "end_offset":36,
            "type":"<ALPHANUM>",
            "position":7
        },
        {
            "token":"you",
            "start_offset":37,
            "end_offset":40,
            "type":"<ALPHANUM>",
            "position":8
        }
    ]
}

其詞根具有順序性(詞根序列)為quick奥额、brown、fox访诱、test 垫挨、we 、will触菜、 like九榔、 to 、you涡相,

如果查詢字符串為 quick brown哲泊,分詞后的詞根序列為 quick brown,則是原詞根序列的子集催蝗,則匹配攻旦。

如果查詢字符串為 quick fox,分詞后的詞根序列為 quick fox生逸,與原詞根序列不匹配。如果指定slop屬性且预,設(shè)置為1槽袄,則匹配,其表示每一個詞根直接跳過一個詞根形成新的序列锋谐,與搜索詞根進行比較遍尺,是否匹配。

如果查詢字符串為quick fox test,其特點是quick與原序列跳過一個詞brown涮拗,但fox后面不跳過任何次乾戏,與test緊挨著,如果指定slop=1三热,同樣能匹配到文檔鼓择,但查詢字符串quick fox test will,卻匹配不到文檔就漾,說明slop表示整個搜索詞根中為了匹配流呐能,能跳過的最大次數(shù)。

按照match_phrase的定義抑堡,與match query的區(qū)別一個在與精確匹配摆出,一個在于詞組term(理解為詞根序列),故match_phrase與match相比首妖,不會有如下參數(shù):fuzziness偎漫、cutoff_frequency、operator有缆、minimum_should_match 這些參數(shù)象踊。

3温亲、match phrase prefix query

與match phrase基本相同,只是該查詢模式會對最后一個詞根進行前綴匹配通危。

GET /_search
{
    "query": {
        "match_phrase_prefix" : {
            "message" : {
                "query" : "quick brown f",
                "max_expansions" : 10
            }
        }
    }
}

其工作流程如下:首先先對除最后一個詞進行分詞铸豁,得到詞根序列 quick brown,然后遍歷整個elasticsearch倒排索引菊碟,查找以f開頭的詞根节芥,依次組成多個詞根流,例如(quick brown fox) (quick brown foot)逆害,默認查找50組头镊,受參數(shù)max_expansions控制,在使用時請設(shè)置合理的max_expansions魄幕,該值越大相艇,查詢速度將會變的更慢。該技術(shù)主要完成及時搜索纯陨,指用戶在輸入過程中坛芽,就根據(jù)前綴返回查詢結(jié)果,隨著用戶輸入的字符越多翼抠,查詢的結(jié)果越接近用戶的需求咙轩。

4、multi match query

multi_match查詢建立在match查詢之上阴颖,允許多字段查詢活喊。

GET /_search
{
  "query": {
    "multi_match" : {
      "query":    "this is a test", 
      "fields": [ "subject", "message" ]   // @1
    }
  }
}

@1執(zhí)行作用(查詢)的字段,有如下幾種用法:

  1. [ "subject", "message" ] 量愧,表示針對查詢自動對subject,message字段進行查詢匹配钾菊。
  2. [ "title", "*_name" ]泼各,支持通配符观游,表示對title,以_name結(jié)尾的字段進行查詢匹配猴鲫。
  3. [ "subject^3", "message" ]软棺,表示subject字段是message的重要性的3倍红竭,類似于字段權(quán)重。

4.1 multi_query重要參數(shù)詳解

4.1.1 type 屬性

指定multi_query內(nèi)部的執(zhí)行方式喘落,取值如下:best_fields茵宪、most_fields、cross_fields瘦棋、phrase稀火、phrase_prefix。

4.1.1.1 best_fields

type默認值赌朋,只要其中一個字段匹配則匹配文檔(match query)凰狞。但是使用最佳匹配的字段的score來表示文檔的分數(shù)篇裁,會影響文檔的排序。

例如有如下兩個文檔赡若,id,title,context字段值分別如下:
doc1 : 1 "Quick brown rabbits" "Brown rabbits are commonly seen brown."
doc2:2 "Keeping pets healthy", "My quick brown as fox eats rabbits on a regular basis."

如果查詢字段“brown fox”字符串达布,兩個文檔的匹配度誰高呢?初步分析如下:查詢字符串"brown fox"會被分詞為brown逾冬、fox兩個詞根黍聂,首先brown在doc1的title、context中都能匹配brown身腻,而且次數(shù)為3次产还,在doc2中,只有在context字段中匹配到brown fox各一次嘀趟,那哪個相關(guān)度(評分score)脐区。

best_fields類型,認為在同一個字段能匹配到更多的查詢字符串詞根她按,則認為該字段更佳牛隅。由于doc2的context字段能匹配到兩個查詢詞根,故doc2的匹配度更高酌泰,doc2會優(yōu)先返回倔叼,對應(yīng)測試代碼:

    public static void testMultiQueue_best_fields() {
        RestHighLevelClient client = EsClient.getClient();
        try {
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("esdemo");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(
                    QueryBuilders.multiMatchQuery("brown fox", "title","context")
                        .type(Type.BEST_FIELDS)
                    );
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(result);
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            EsClient.close(client);
        }
    }

執(zhí)行的查詢結(jié)果如下:

{
    "took":4,
    "timed_out":false,
    "_shards":{
        "total":5,
        "successful":5,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":2,
        "max_score":0.5753642,
        "hits":[
            {
                "_index":"esdemo",
                "_type":"matchquerydemo",
                "_id":"2",
                "_score":0.5753642,
                "_source":{
                    "context":"My quick brown as fox eats rabbits on a regular basis.",
                    "title":"Keeping pets healthy"
                }
            },
            {
                "_index":"esdemo",
                "_type":"matchquerydemo",
                "_id":"1",
                "_score":0.2876821,
                "_source":{
                    "context":"Brown rabbits are commonly seen.",
                    "title":"Quick brown rabbits"
                }
            }
        ]
    }
}

best_fields類型內(nèi)部會轉(zhuǎn)換為(dis_max):

GET /_search
        {
            "query": {
                    "dis_max": {
                        "queries": [
                            { "match": { "subject": "brown fox" }},
                            { "match": { "message": "brown fox" }}
                        ],
                        "tie_breaker": 0.3
                    }
            }
        }

通常best_fields類型使用單個最佳匹配字段的分數(shù),但如果指定了tie_breaker宫莱,則其計算結(jié)果如下:最佳匹配字段的分數(shù)加上 tie_breaker * _score(其他匹配字段分數(shù))。該查詢模式支持match query相關(guān)的參數(shù)哩罪,例如analyzer, boost, operator, minimum_should_match, fuzziness, lenient, prefix_length, max_expansions, rewrite, zero_terms_query, cutoff_frequency, auto_generate_synonyms_phrase_query 授霸、fuzzy_transpositions等參數(shù)。

best_fields和大多數(shù)字段類型都是以字段為中心的——它們?yōu)槊總€字段生成匹配查詢际插。這意味著運算符和minimum_should_match參數(shù)將分別應(yīng)用于每個字段碘耳。

4.1.1.2 most_fields

查找匹配任何字段并結(jié)合每個字段的_score的文檔框弛,Elasticsearch會為每個字段生成一個match查詢辛辨,然后將它們包含在一個bool查詢中。其算法的核心是各個字段的評分相加作為文檔的最終得分參與排序瑟枫。其建議場景是不同字段對同一關(guān)鍵字的存儲維度不一樣斗搞,例如字段一可能包含同義詞、詞干慷妙、變音符等僻焚;字段二可能包含原始詞根,這種情況下綜合各個字段的評分就會顯的更加具有相關(guān)性膝擂。
該查詢模式支持match query相關(guān)的參數(shù)虑啤,例如analyzer, boost, operator, minimum_should_match, fuzziness, lenient, prefix_length, max_expansions, rewrite, zero_terms_query, cutoff_frequency, auto_generate_synonyms_phrase_query 隙弛、fuzzy_transpositions等參數(shù)。

4.1.1.3 phrase狞山、phrase_prefix

這兩種類型score的計算采用best_fields方法全闷,但是其查詢方式分別為match_phrase、match_phrase_prefix萍启。

4.1.1.4 cross_fields

交叉字段总珠,對于需要匹配多個字段的結(jié)構(gòu)化文檔,cross_fields類型特別有用伊约。例如姚淆,在查詢“Will Smith”的first_name和last_name字段時,在一個字段中可能會有“Will”屡律,而在另一個字段中可能會有“Smith”腌逢。這聽起來很象most_fields,cross_fields與most_fields的兩個明顯區(qū)別如下:

對于opreator超埋、minimum_should_match的作用域不一樣搏讶,most_fields是針對字段的,(遍歷每個字段霍殴,然后遍歷查詢詞根列表媒惕,進行逐一匹配),而cross_fields是針對詞根的来庭,即遍歷詞根列表妒蔚,搜索范圍是所有字段。

相關(guān)性的考量不相同月弛,cross_fields重在這個交叉匹配肴盏,對于一組查詢詞根,一部分出現(xiàn)在其中一個字段帽衙,另外一部分出現(xiàn)在另外一個字段中菜皂,其相關(guān)性計算評分將更高。
舉例說明:例如有如下查詢語句:

{
        "query": {
                "multi_match" : {
                    "query":      "Will Smith",
                    "type":       "cross_fields",
                    "fields":     [ "first_name", "last_name" ],
                    "operator":   "and"
                }
        }
    }

其執(zhí)行操作時厉萝,首先對查詢字符串分析得出will恍飘、smith兩個詞根,然后遍歷這兩個詞根谴垫,一次對 first_name,last_name 進行匹配章母,也就是說 opreator、minimum_should_match 這些參數(shù)作用2次翩剪,而 most_fields 方式胳施,是一個嵌套循環(huán),先遍歷字段肢专,然后對每一個詞根在該字段上進行匹配舞肆,在該示例中焦辅,opreator、minimum_should_match 這些參數(shù)作用4次椿胯。

4.1.2 tie_breaker屬性

默認情況下筷登,每個詞匯混合查詢將使用組中任何字段返回的最佳分數(shù),然后將這些分數(shù)相加哩盲,以給出最終分數(shù)前方。tie_breaker參數(shù)可以改變每項混合查詢的默認行為。tie_breaker可選值如下:

  • 0.0 : 默認行為廉油,使用最佳字段的score惠险。
  • 1.0 :所有匹配字段socre的和。
  • 0.0 ~ 1.0 : 使用最佳匹配字段的score + (其他匹配字段score) * tie_breaker抒线。

4.1.3 multi_query支持其他match query參數(shù)

其他諸如analyzer, boost, operator, minimum_should_match, fuzziness, lenient, prefix_length, max_expansions, rewrite, zero_terms_query, cutoff_frequency, auto_generate_synonyms_phrase_query 班巩、fuzzy_transpositions等參數(shù),multi_query同樣支持。

5嘶炭、common terms query

定位:排除停用詞或高頻詞對文檔的匹配影響抱慌。提高文檔匹配的精確度,同時不對性能產(chǎn)生影響眨猎。

我們來看一個停用詞(高頻詞)對文檔過濾帥選帶來的影響:

查詢字符串中的每個詞根都有搜索成本抑进。搜索“the brown fox”需要三個詞根查詢,分別為“The”睡陪、“brown”和“fox”寺渗,所有這些查詢都是針對索引中的所有文檔執(zhí)行的。

對于“The”的查詢可能匹配許多文檔兰迫,因此對相關(guān)性的影響要比其他兩個術(shù)語小得多户秤。
一種解決這個問題的方法是忽略高頻項。通過將“the”視為stopword(停用詞)逮矛,我們可以減少索引大小并減少需要執(zhí)行的詞匯查詢的數(shù)量。這種方法的問題在于转砖,盡管停止語對相關(guān)性的影響很小须鼎,但它們?nèi)匀缓苤匾?/p>

如果我們?nèi)サ魋topwords,我們就會失去精確性(比如我們無法區(qū)分“快樂”和“不快樂”)府蔗,我們就會失去回憶(比如像“The The The”或“to be or not to be”這樣的文本就不會存在于索引中)晋控。

本文將介紹另外一種方式來解決上述問題:
common terms query 將查詢詞根分為兩組:更重要的(即低頻詞根)和不那么重要的(即高頻詞根,以前應(yīng)該是停止詞)姓赤。

首先赡译,它搜索與更重要的詞根(低頻詞)匹配的文檔。這些術(shù)語出現(xiàn)在較少的文檔中不铆,對相關(guān)性的影響更大蝌焚,性能更好裹唆。

然后,它對不太重要的詞根(高頻詞)執(zhí)行第二個查詢只洒。但是它并不會計算所有匹配(匹配高頻詞的所有文檔)文檔的相關(guān)得分许帐,而是只計算第一個查詢已經(jīng)匹配的文檔的_score。通過這種方式毕谴,高頻項可以在不付出性能差的代價的情況下改進關(guān)聯(lián)計算(低頻詞成畦、高頻次相互關(guān)聯(lián))。

如果查詢只包含高頻術(shù)語涝开,那么一個查詢將作為AND(連接)查詢執(zhí)行循帐,換句話說,所有的詞根都必須滿足舀武。盡管每個單獨的詞根將匹配許多文檔拄养,但術(shù)語組合將結(jié)果集縮小到最相關(guān)的部分,當(dāng)然單個查詢也可以作為或以特定的minimum_should_match執(zhí)行奕剃。
詞根根據(jù)cutoff_frequency被分配給高頻或低頻組衷旅,可以指定為絕對頻率(>=1)或相對頻率(0.0)。1.0)纵朋。

5.1 示例詳解

5.1.1 簡單使用說明

GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "this is bonsai cool",
                "cutoff_frequency": 0.001
            }
        }
    }
}

會對查詢詞根 this柿顶、is、bonsai操软、cool4個詞根分詞嘁锯,詞根頻率小于0.001的bonsail、cool會被當(dāng)成低頻次聂薪,而this家乘、is會被設(shè)置為高頻詞組。由于common term query將詞根分成了低頻組與高頻組藏澳,故針對match query的operator仁锯、minimum_should_match分別由如下四個參數(shù)代替:low_freq_operator、high_freq_operator翔悠、minimum_should_match:{low_freq业崖、hign_freq}。

java rest api使用示例如下:

public static void testCommonQuery() {
        RestHighLevelClient client = EsClient.getClient();
        try {
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("esdemo");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(
                    QueryBuilders.commonTermsQuery("context", "this is brown fox")
                        .cutoffFrequency(0.001f)
                        .highFreqOperator(Operator.OR)
                        .highFreqMinimumShouldMatch("3")
                        .lowFreqOperator(Operator.OR)
                        .lowFreqMinimumShouldMatch("2")
                    );
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(result);
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            EsClient.close(client);
        }
    }

6蓄愁、query_string query

查詢字符串方式双炕。query_string查詢解析器支持對查詢字符串按照操作符進行切割,每個部分獨立分析撮抓,例如:

GET /_search
{
    "query": {
        "query_string" : {
            "default_field" : "content",
            "query" : "(new york city) OR (big apple)"
        }
    }
}

query_string的頂層參數(shù)如下:

參數(shù)名 描述
query 查詢字符串妇斤。
default_field 默認匹配字段,如果未設(shè)置,則為"*"站超,表示所有的字段荸恕,也可通過index.query.default_field來統(tǒng)一配置默認字段。
default_operator 設(shè)置默認操作類型顷编,可選值:Operator.OR 和 Operator.AND戚炫,默認為Operator.OR。
analyzer 設(shè)置分詞器媳纬。
quote_analyzer 用于分析查詢字符串中引用的短語的分析器的名稱双肤。對于這些部分,它覆蓋了使用analyzer參數(shù)或search_quote_analyzer設(shè)置設(shè)置的其他分析器钮惠。
allow_leading_wildcard 是否允許第一個字符為通配符(*或?),默認為允許茅糜。
enable_position_increments 是否允許以在結(jié)果查詢中啟用位置增量。默認值為true素挽。
fuzzy_max_expansions 控制模糊匹配的詞根的擴展個數(shù)蔑赘,在match phrase prefix的max_expansions已詳解,默認為50预明。
fuzziness 設(shè)置為模糊匹配缩赛。
fuzzy_prefix_length 模糊查詢設(shè)置前綴長度。默認值為0撰糠。
fuzzy_transpositions 是否開啟模糊互換(ab -> ba)酥馍。默認為true。
phrase_slop match_phrase查詢的slop阅酪。
boost 設(shè)置查詢的boost值旨袒。默認為1.0。
auto_generate_phrase_queries 是否自動生成短語查詢(match_phrase)术辐,默認為false砚尽。
analyze_wildcard 默認情況下,查詢字符串中的通配符項不會被分析辉词。通過將該值設(shè)置為true必孤,還將盡力分析這些值。
max_determinized_states 設(shè)置可以創(chuàng)建自動狀態(tài)機(正則表達式)瑞躺,默認為 10000敷搪。
minimum_should_match 具體參考match_query的minimum_should_match。
lenient 是否忽略由于數(shù)據(jù)類型不匹配引起的異常隘蝎,默認為false
time_zone 時區(qū)應(yīng)用于與日期相關(guān)的任何范圍查詢。參見JODA時區(qū)襟企。
auto_generate_synonyms_phrase_query 在使用match_phrase_query查詢時開啟同義詞匹配嘱么,默認為true.
all_fields 6.4.0版本后已廢棄,使用default_field顽悼。

6.1 多字段支持(multi field)

query_string支持多字段查詢曼振,可通過fields屬性指定几迄,例如:

GET /_search
{
    "query": {
        "query_string" : {
            "fields" : ["content", "name"],
            "query" : "this AND that"
        }
    }
}

其含義類似于:"query": "(content:this OR name:this) AND (content:that OR name:that)"。

同時query_string(查詢字符串)模式同樣支持match_query等查詢對應(yīng)的參數(shù)冰评,其工作機制一樣映胁,示例如下:

GET /_search
{
    "query": {
        "query_string" : {
            "fields" : ["content", "name^5"],
//          "fields" : ["city.*"],
            "query" : "this AND that OR thus",
            "tie_breaker" : 0,
             "type": "best_fields",
  "auto_generate_synonyms_phrase_query" : false    (同義詞synonym機制)
        }
    }
}

6.2 支持通配符

查詢字符串中支持使用通配符?與,其中?表示的單個字符甲雅,而表示0個或多個字符解孙。查詢字符串使用通配符,可能會消耗更多的內(nèi)存抛人,查詢性能較低下弛姜。為了提高通配符效率,如果只是一個的話妖枚,命令就會被重寫為存在查詢(是否存在文檔)廷臼,例如fields:[""]。在關(guān)系型數(shù)據(jù)庫中前置通配符(" ab")绝页,這種查詢是不支持索引查詢的荠商,在es中同樣如此,需要遍歷索引中所有詞根续誉,可以通過allow_leading_wildcard=false來禁用這種查詢莱没。通過將analyze_wildcard設(shè)置為true,將分析以結(jié)尾的查詢屈芜,并從不同的令牌構(gòu)建布爾查詢郊愧,方法是確保第一個N-1令牌上的精確匹配,以及最后一個令牌上的前綴匹配井佑。

6.3 支持正則表達式

正則表達式可以嵌入到查詢字符串中属铁,方法是將它們包裝成斜杠("/")。注意allow_leading_wildcard無法控制正則表達式的行為躬翁。

6.4 鄰近查詢(可前可后)

雖然短語查詢match_phrase(如“john smith”)要求所有的術(shù)語都按照完全相同的順序進行查詢焦蘑,但是接近查詢允許指定的單詞進一步分開或以不同的順序進行查詢,并且也提供諸如match_query的slop屬性。例如:"fox quick"~5盒发。

6.5 范圍查詢

可以為日期例嘱、數(shù)字或字符串字段指定范圍查詢。包含范圍用方括號[min到max]指定宁舰,排他范圍用花括號{min到max}指定拼卵。例如如下:

  • 日期在2012年之內(nèi)。
    date:[2012-01-01 TO 2012-12-31]
  • 大于等1蛮艰,小于等5
    count:[1 TO 5]
  • Tags在 alpha 和omega之間腋腮,但不包括alpha和omega
    tag:{alpha TO omega}
  • 大于等于10
    count:[10 TO *]
  • 日期小于2012年
    date:{* TO 2012-01-01}

6.6 搜索字符串權(quán)重提升

使用提高運算符可以設(shè)置一個詞根相比其他詞根更加重要(相關(guān)性更高)。例如針對查詢字符串"quick2 fox",表明quick這個詞根的重要性比fox重要2倍即寡。該操作符也可以針對短語或組徊哑,一個組用()表示,示例如下:"john smith"^2 (foo bar)^4聪富。

6.7 boolean運算

默認情況下莺丑,所有詞根都是可選的,只要一個詞根匹配即可(Opreator.OR),從上面得知通過修改default_operator可以改變其默認行為墩蔓。ES還支持對查詢字符串進行boolean運算梢莽。例如查詢字符串“quick brown +fox -news”表示的含義是:

  1. fox詞根必須存在。
  2. news詞根必須不存在钢拧。
  3. quick brown 可選蟹漓。
    也支持常見的布爾運算符AND, OR和NOT(也寫為&&,||和!)源内,但要注意葡粒,它們不遵守通常的優(yōu)先規(guī)則,因此當(dāng)多個運算符一起使用時膜钓,應(yīng)該使用括號嗽交。例如,前面的查詢可以改寫為:((quick AND fox) OR (brown AND fox) OR fox) AND NOT news颂斜。

6.8 分組(grouping)

多個詞根或子句可以用括號組合在一起夫壁,形成子查詢,例如(quick OR brown) AND fox沃疮。

6.9 轉(zhuǎn)義字符

在ES中盒让,如下字符需要使用轉(zhuǎn)義符合\,保留字符是:+ - = && || > < !(){ }[]”^ ~ * ?:\ /司蔬。

6.10 空查詢

如果查詢字符串為空或僅包含空白邑茄,則查詢將生成空結(jié)果集。

6.11 query_string示例

public static void testQueryStringQuery_Query() {
        RestHighLevelClient client = EsClient.getClient();
        try {
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("esdemo");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(
//                  QueryBuilders.queryStringQuery("brown -fox")
//                  QueryBuilders.queryStringQuery("brown^8 fox^2")
                    QueryBuilders.queryStringQuery("(quick OR brown) AND fox")
                        .allowLeadingWildcard(false)
                        .field("context")
                        .field("title")
//                      .minimumShouldMatch("1")
                    );
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(result);
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            EsClient.close(client);
        }
    }

測試情況如下:
目前范圍查詢暫不知如何編寫查詢字符串俊啼,但ES專門通過QueryBuilders.rangeQuery(String name)返回RangeQueryBuilder肺缕,鄰近查詢未能編寫Demo。

7授帕、simple_query_string query

簡單字符串查詢模式同木。使用SimpleQueryParser解析上下文的查詢。與常規(guī)的query_string查詢不同跛十,simple_query_string查詢永遠不會拋出異常彤路,并丟棄查詢的無效部分。下面是一個例子:

GET /_search
{
  "query": {
    "simple_query_string" : {
        "query": "\"fried eggs\" +(eggplant | potato) -frittata",
        "fields": ["title^5", "body"],
        "default_operator": "and"
    }
  }
}

查詢字符串的寫法非常符合(query_string)中定義的芥映,例如查詢字符串中支持boolean運算等洲尊。simple_query_string中的頂級參數(shù)都定義在org.elasticsearch.index.query.SimpleQueryStringBuilder中缝裤,其含義與query_string中類似,在這里就不重復(fù)介紹了颊郎。
simple_query_string支持如下寫法。

  • +signifies 表示必須包含霎苗。
  • | signifies 相當(dāng)于OR姆吭。
  • negates 相當(dāng)于非
  • " 包裝一些標(biāo)記以表示搜索的短語
    • 例如a*,表示前綴匹配
  • ( and ) 括號可表示優(yōu)先級
  • ~N after a word 表示模糊匹配舉例唁盏,類似于match_phrase slop内狸。
  • ~N after a phrase(短語),表示溢出量厘擂。

上述這些寫法與在query_string機制一樣昆淡。接下來主要再講述query_string不同點。

7.1 flags

simple_query_string支持多個標(biāo)記來指定應(yīng)該啟用哪些解析特性刽严。它被指定為一個|分隔的字符串,例如:

GET /_search
{
    "query": {
        "simple_query_string" : {
            "query" : "foo | bar + baz*",
            "flags" : "OR|AND|PREFIX"
        }
    }
}

可用的flag的列表如下:ALL, NONE, AND, OR, NOT, PREFIX, PHRASE, PRECEDENCE, ESCAPE, WHITESPACE, FUZZY, NEAR, and SLOP昂灵。

7.2 使用示例

public static void testSimpleQueryString_Query() {
        RestHighLevelClient client = EsClient.getClient();
        try {
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("esdemo");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(
                    QueryBuilders.simpleQueryStringQuery("brown -fox")
                    );
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(result);
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            EsClient.close(client);
        }
    }

關(guān)于es 的全文檢索就介紹到這里了。


更多文章建議關(guān)注我的個人公眾號:


中間件興趣圈
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舞萄,一起剝皮案震驚了整個濱河市眨补,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌倒脓,老刑警劉巖撑螺,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異崎弃,居然都是意外死亡甘晤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門饲做,熙熙樓的掌柜王于貴愁眉苦臉地迎上來线婚,“玉大人,你說我怎么就攤上這事艇炎∽靡粒” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵缀踪,是天一觀的道長居砖。 經(jīng)常有香客問我,道長驴娃,這世上最難降的妖魔是什么奏候? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮唇敞,結(jié)果婚禮上蔗草,老公的妹妹穿的比我還像新娘咒彤。我一直安慰自己,他們只是感情好咒精,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布镶柱。 她就那樣靜靜地躺著,像睡著了一般模叙。 火紅的嫁衣襯著肌膚如雪歇拆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天范咨,我揣著相機與錄音故觅,去河邊找鬼。 笑死渠啊,一個胖子當(dāng)著我的面吹牛输吏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播替蛉,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼贯溅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了躲查?” 一聲冷哼從身側(cè)響起盗迟,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎熙含,沒想到半個月后罚缕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡怎静,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年邮弹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚓聘。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡腌乡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出夜牡,到底是詐尸還是另有隱情与纽,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布塘装,位于F島的核電站急迂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蹦肴。R本人自食惡果不足惜僚碎,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望阴幌。 院中可真熱鬧勺阐,春花似錦卷中、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至懒闷,卻和暖如春无埃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背毛雇。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留侦镇,地道東北人灵疮。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像壳繁,于是被迫代替她去往敵國和親震捣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容