ElasticSearch Query DSL

ElasticSearch 查詢DSL(Domain Specific Language便锨,領(lǐng)域特定語(yǔ)言),基于6.8.15版本 語(yǔ)法筆記吉捶。

  • Query Context(查詢上下文): 除了判斷文檔是否匹配外夺鲜,查詢子句還會(huì)計(jì)算_score元數(shù)據(jù)字段中的相關(guān)性分?jǐn)?shù)。每個(gè)查詢子句要表達(dá)的含義是“此文檔與此查詢子句匹配程度如何呐舔?”
  • Filter Context(過濾器上下文):過濾上下文主要用于過濾結(jié)構(gòu)化數(shù)據(jù)币励,Elasticsearch 會(huì)自動(dòng)緩存常用的過濾器,以提高性能珊拼。每個(gè)查詢子句表達(dá)的含義是“此文檔是否與此查詢子句匹配食呻?”

Compounded Queries(混合查詢)

Boolean Query

通過mustshould澎现、must_notfilter組織查詢條件仅胞,形成一種或與非邏輯查詢。允許邏輯嵌套剑辫。

  • must:必須滿足的條件干旧,相當(dāng)于 and
  • should:滿足其中一個(gè)條件即可,相當(dāng)于 or
  • must not:必須不滿足條件妹蔽,相當(dāng)于 not 椎眯,不會(huì)參與評(píng)分
  • filter:與 must 含義相同,不參與評(píng)分

舉例:

// type 是低版本的概念胳岂,后續(xù)已經(jīng)被作廢编整。6.8可以填_doc 或者 不填寫
POST /users{/_doc}/_search
{
  "query": {
    "bool" : {
      //注意這里的不同
      //_name 字段給每個(gè)查詢條件起一個(gè)名字
      //這樣在查詢記錄里就會(huì)多一個(gè) matched_queries 來指明命中了那些條件
      "must" : {
        "term" : { 
            "user.id" : {"query":"kimchy" ,"_name":"fist"}
        }
      },
      "filter": {"term" : { "tags" : "production" } },
      "must_not" : {"range" : {"age" : { "gte" : 10, "lte" : 20 }}},
      "should" : [
        { "term" : { "tags" : "env1" } },
        { "term" : { "tags" : "deployed" } }
      ],
      //表示,should中n個(gè)條件乳丰,必須滿足其中n個(gè)闹击,默認(rèn)為1
      "minimum_should_match" : 1,
      // 最終得分 = 分?jǐn)?shù) * boost
      "boost" : 1.0
    }
  }
}

Boosting Query

POST /articles/_search
通過 positivenegative 兩種搜索條件的匹配,來正面(positive)或負(fù)面(negative)影響 _score 的計(jì)算成艘。

POST /articles/_search
{
  "query": {
    "boosting": {
      //必須要滿足的條件
      "positive": {
        "match": {
          "title": "Java"
        }
      },
      //扣分條件赏半,滿足條件則最終分?jǐn)?shù) = positive 匹配得分 * negative_boost
      "negative": {
        "match": {
          "title": "developer"
        }
      }, 
      "negative_boost": 0.1
    }
  }
}

Constant Score Query

因?yàn)?code>filter查詢,并不會(huì)計(jì)算分?jǐn)?shù)淆两,因此這種方式可以為其查詢結(jié)果給出一個(gè)固定分?jǐn)?shù)断箫。

POST /articles/_search
{
  "query": {
    "constant_score": {
      //這里必須是filter
      "filter": {
        "term": {
          "title.keyword": "Java developer"
        }
      },
      // filter 最終的得分為 1.2
      "boost": 1.2
    }
  }
}

Dis Max Query (DisjunctionMaxQuery)

通過多個(gè)查詢條件匹配文檔,以匹配條件中最高分?jǐn)?shù)作為最終得分秋冰,其他非高分匹配的條件仲义,需要通過tie_breaker 來影響得分。

POST /articles/_search
{
  "query": {
    "dis_max": {
      //標(biāo)識(shí)非最高分匹配命中,分?jǐn)?shù)需要 乘以 0.7
      "tie_breaker": 0.7,
      //用于指定 Constant Score Query 這種的固定分?jǐn)?shù)埃撵,constant_query 里面指定的優(yōu)先
      "boost": 1.2,
      //有多個(gè)匹配條件赵颅,假設(shè)第一匹配分?jǐn)?shù)最高
      //最終得分 = 第一個(gè)匹配得分 + 第二個(gè)匹配得分 * 0.7
      "queries": [
        {"match": {"title": "Java developer"}},
        {"match": {"content": "Java"}},
        {"constant_score": {
          "filter": {
            "term": {
              "title.keyword": "Java developer"
            }
          },
          //這個(gè)比外面的boost優(yōu)先級(jí)高
          "boost": 3
        }}
      ]
    }
  }
}

Function Score Query

通過一些函數(shù)來計(jì)算最終的得分情況。
final_score = boost_mode(query_score,score_mode(fun_score_1...2))

  • score_mode:multiply暂刘、sum饺谬、avg频丘、first腌巾、max、min
  • boost_mode:multiply审葬、replace(特殊森缠,只使用func_score拔鹰,不用query_socre)、sum贵涵、avg列肢、max、min
  • function:weight(不指定就是它)宾茂、field_value_factor(基于指定字段)例书、script_score(通過函數(shù)腳本)、衰減函數(shù) (linear刻炒、exp决采、guass) 和 random_score(0到1浮點(diǎn)隨機(jī)數(shù))

下面這個(gè)例子基于:

function: weight、field_value_factor

score_mode: sum

boost_mode: sum

POST /articles/_search
{
  "query": {
    "function_score": {
     
      "boost":2,
      //這里使用 match_all 不會(huì)打分去 boost = 2坟奥,所以 query_score = 2
      "query": {"match_all": {}},
      "functions": [
        //符合次filter匹配的 fun_score_1 = size(假設(shè)10) * weight = 20
        {
          "filter": {
            "term": {
              "title.keyword": "Java developer"
            }
          },
          "weight": 2,
          "field_value_factor": {
            "field": "size"
          }
        },
        //符次filter條件的 fun_score_2 = weight = 2
        {
          "filter": {
            "match":{
              "content":"Spring"
            }
          },
          "weight": 2
        },
        //符次filter條件的 fun_score_3 = weight = 1
        {
          "filter": {
            "match":{
              "content":"NIO"
            }
          },
          "weight": 1
        }
      ],
      //functions 中多個(gè)計(jì)分方式树瞭,他們之間是通過累加的方式
      //即 fun_score = sum(fun_score_1,fun_score_2,fun_score_3) = 23
      "score_mode": "sum",
      //最終得分 = sum(query_score,fun_score)
      "boost_mode": "sum",
      // 指定 functions 的最終打分不能超過 30 Math.min(fun_score,30)
      "max_boost": 30
    }
  }
}

// script_score 使用,替代上面的 fun_score_1 中 field_value_factor 即可
"script_score": {
  "script": {
    "params": {
      "a": 5,
      "b": 1.2
    },
    "source": "params.a / Math.pow(params.b, doc['my-int'].value)"
  }
}

Full Text Queries(全文本搜索)

match

將查詢文本分詞后爱谁,在指定字段上進(jìn)行匹配晒喷。
萊文斯坦距離:指兩個(gè)字符串之間,由一個(gè)轉(zhuǎn)成另一個(gè)所需的最少編輯操作次數(shù)访敌。

  • 將一個(gè)字符替換成另一個(gè)字符
  • 插入一個(gè)字符
  • 刪除一個(gè)字符
POST /articles/_search
{
  "query": {
    "match": {
      "content": {
        //這個(gè)文本會(huì)被凉敲,下面的 analyzer 
        "query": "ja1a spr0ng",
        "analyzer": "standard",
         //表示分詞成term之后,查詢是通過and連接的寺旺,默認(rèn)是or
        "operator": "and",
        //表示是否忽略類型轉(zhuǎn)換錯(cuò)誤
        //比如說通過 size 字段(數(shù)值類型)查詢傳了一個(gè) 字符串默認(rèn) false 會(huì)報(bào)錯(cuò)的
        "lenient": "true",
        //標(biāo)識(shí)是否啟用模糊查詢爷抓,使用 Levenshtein Edit Distance  萊文斯坦距離做模糊匹配
        //默認(rèn)是0,標(biāo)識(shí)精確匹配
        //AUTO表示 0-2 必須精確 3-5 支持最小編輯為1 5 以上最小編輯為 2
        "fuzziness": "AUTO",
        //模糊查詢時(shí)阻塑,term 的前 2 個(gè)必須一樣蓝撇,從第三個(gè)字符開始允許編輯
        "prefix_length": 2,
        //表示是否過濾掉停用次,默認(rèn)是none陈莽,如果期望不過濾使用 all
        "zero_terms_query": "none",
        //定義高頻詞渤昌,分?jǐn)?shù)表示虽抄,term 出現(xiàn)頻率 正數(shù)表示出現(xiàn)次數(shù)
        //在 operator 為 and match 會(huì)被改寫成 bool 查詢邏輯,低頻次是一個(gè)must的邏輯独柑,高頻詞是should的邏輯迈窟,高頻詞會(huì)影響到最終的得分
        "cutoff_frequency": 2
      }
    }
  }
}

match_phrase

相比于matchmatch_phrase 外強(qiáng)調(diào)了term的位置忌栅,也就是要求匹配文本具有一定的語(yǔ)法順序车酣。可以用來做用戶輸入補(bǔ)全狂秘。

POST /articles/_search
{
  "query": {
    "match_phrase": {
      "content": {
        //Unity3d 和 DDL 這兩個(gè)詞必須存在骇径,并且順序先后出現(xiàn)
        "query": "Unity3d DDL",
        //表示 Unity3d 和 DDL 中間只能差一個(gè)詞
        "slop": 1
      }
    }
  }
}

match_phrase_prefix

match_phrase 一樣的躯肌,但最后一個(gè)詞可以只給前綴

{
  "query": {
    "match_phrase_prefix": {
      "content": {
        "query": "Spring Fr",
        //這個(gè)參數(shù)者春??清女?
        "max_expansions": 0
      }
    }
  }
}

multi_match

文檔多字段匹配

POST /articles/_search
{
  "query": {
    "multi_match": {
      "query": "spring",
      //content^3^3 表示content字段匹配打分會(huì) 乘以 3
      //titl* 表示模糊匹配字段钱烟,如果匹配不到會(huì)報(bào)錯(cuò)
      "fields": ["content^3","titl*"]
    }
  }
}

common

common存在是為了提高,低頻次的匹配精度嫡丙,降低停用詞的影響但不排除停用詞拴袭。
在實(shí)際匹配過程中,如果停用詞參與了匹配那么曙博,那么結(jié)果會(huì)出現(xiàn)很多無關(guān)文檔拥刻,如果省略掉則會(huì)造成失語(yǔ)現(xiàn)象,如“no happy” no被去掉后可能就變成“haapy”父泳。這時(shí)候就可以用common

POST /articles/_search
{
  "query": {
    "common": {
      "content": {
        //實(shí)際會(huì)被解析成BooleanQuery
        "query": "no Spring Framework",
        "cutoff_frequency": 0.001,
        //再and的情況下
        //非停用詞是must邏輯
        //停用詞是 should 邏輯
        "low_freq_operator": "and"
      }
    }
  },
  "profile": "true"
}

Term-level queries

term

針對(duì)term進(jìn)行查詢般哼,如果是 exact_value(keyword)他不會(huì)被分詞,term就是文本本身惠窄,如果是 full_text 文本會(huì)被分詞器分成n多個(gè)term蒸眠,只要其中有任何一個(gè)term在 查詢條件內(nèi)就會(huì)返回。

POST /articles/_search
{
  "query": {
    "term": {
      "content": {
        //這里的值一定是分詞后的term值杆融,區(qū)分大小寫
        //雖然full_text 里面可能是Spring楞卡,分詞后是spring ,那就應(yīng)該用spring查詢
        "value": "spring",
        //最終打分結(jié)果會(huì)乘以 boost
        "boost": 0
      }
    }
  }
}

Terms Query

只要字段中包括其中一個(gè)term就會(huì)返回脾歇,也允許講其他文檔的字段值作為查詢條件蒋腮。

POST /articles/_search
{
  "query": {"terms": {"content": ["spring","cloud"]}}
}

GET /tweets/_search
{
    "query" : {
        "terms" : {
            "user" : {
                //使用 index=users type=_doc id=2  path=followers(字段)的值作為terms query查詢
                "index" : "users",
                "type" : "_doc",
                "id" : "2",
                "path" : "followers"
            }
        }
    }
}

Terms Set Query

與terms query 一樣,但是可以額外制定必須匹配數(shù)量藕各,這個(gè)數(shù)量可以來源于文檔的字段徽惋,或者通過腳本計(jì)算。


POST /users/_search
{
  "query": {
    "terms_set":{
      "followers":{
        "terms":[1,30],
        // 這個(gè)表示匹配的數(shù)量必須是字段num的value
        # "minimum_should_match_field":"num",
        // 這里指明匹配的數(shù)量必須是 terms 數(shù)組的長(zhǎng)度
        "minimum_should_match_script": {
            // Math.min(params.num_terms, doc['required_matches'].value)
           "source": "params.num_terms"
        }
      }
    }
  }
}

Range Query

范圍查詢 gt(大于)gte(大于等于)lt(小于)lte(小于等于)

POST /users/_search
{
  "query": {
    "range": {
      "num": {
        "gte": 1,
        "lte": 20
      }
    }
  }
}

POST /users/_search
{
  "query": {
    "range": {
      "birthday": {
        //日期字段可以使用now-1d/d 表示大于當(dāng)前時(shí)間減一天的數(shù)據(jù)
        //這部分函數(shù)可以查看 Date Math 相關(guān)文檔
        "gt": "now-1d/d"
      }
    }
  }
}

Exists Query

查詢字段不為null 或 [] 的文檔座韵,如果想表達(dá) not exists 就必須用 bool query 包裝

POST /users/_search
{
  "query": {
    "exists": {
      "field": "followers"
    }
  }
}

POST /users/_search
{
  "query": {
    "bool": {
      "must_not": [
        {"exists": {"field": "followers"}}
      ]
    }
  }
}

Prefix Query

文本不分詞险绘,進(jìn)行前綴查詢

GET /_search
{ "query": {
    "prefix" : { "user" : "ki" }
  }
}

Wildcard Query

term 模糊匹配踢京,* 0個(gè)或者多個(gè)字符 ? 表示 任何一個(gè)字符

POST /users/_search
{
  "query": {
    "wildcard": {
      "username.keyword": {
        "value": "111 ? 222"
      }
    }
  }
}

Regexp Query

正則表達(dá)式匹配,運(yùn)行速度取決于正則表達(dá)式 .* 都非常慢宦棺,應(yīng)該盡可能使用長(zhǎng)前綴匹配瓣距。

  • . 表示任意一個(gè)字符
    • 表示前一個(gè)字符出現(xiàn)1次或者多次
    • 表示前一個(gè)字符出現(xiàn)0次或者多次
  • ? 表示出現(xiàn)0次或者一次
  • {1,4} 表示出現(xiàn) 大于等于1次 小于等于 4次 {4}表示出現(xiàn)4次,{2,}表示出現(xiàn)2次以上
  • (ab)+ 表示(ab)一組出現(xiàn) 1次或者多次
  • | 表示 一個(gè)or 的邏輯 如 aa|bb aa or bb
  • [abc] 表示 abc [a-c] 表示 abc [^abc] 表示 非 abc \ 用來表示轉(zhuǎn)義 可以轉(zhuǎn)移 -
  • ab~cd 表示 以a 開頭緊接著是b 然后跟個(gè)非c的任何字符代咸,以f結(jié)尾
  • <1-100> 表示一個(gè)時(shí)間范圍蹈丸,可以匹配到80
  • & 表示前后兩個(gè)正則都需要滿足,aaa.+&.+bbb aaabbb match
  • @ 表示跟任何 string 都匹配
POST /users/_search
{
  "query": {
    "regexp": {
      "username.keyword": "111.*"
    }
  }
}

Fuzzy Query

最大編輯舉例匹配(萊文斯坦距離)

POST /users/_search
{
  "query": {
    "fuzzy": {
      "username.keyword": {
        "value": "111 2 2",
        //表示最大可以編輯兩次
        "fuzziness": 2,
        //前面6個(gè)字符必須一樣
        "prefix_length": 6,
        //呐芥?逻杖??
        "max_expansions": 100
      }
    }
  }
}

Type Query

index 下 類型查找思瘟,之后類型被弱化了荸百,所以沒什么用了

POST /users/_search
{
  "query": {
    "type":{
      "value":"_doc"
    }
  }
}

Ids Query

查詢制定id的文檔

GET /users/_search
{
    "query": {
        "ids" : {
            "type" : "_doc",
            "values" : ["1", "4", "100"]
        }
    }
}

操作的時(shí)候不制定前面的索引,直接使用/_search 將會(huì)搜索所有的索引

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末滨攻,一起剝皮案震驚了整個(gè)濱河市够话,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌光绕,老刑警劉巖女嘲,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诞帐,居然都是意外死亡欣尼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門停蕉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來愕鼓,“玉大人,你說我怎么就攤上這事谷徙【軉” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵完慧,是天一觀的道長(zhǎng)谋旦。 經(jīng)常有香客問我,道長(zhǎng)屈尼,這世上最難降的妖魔是什么册着? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮脾歧,結(jié)果婚禮上甲捏,老公的妹妹穿的比我還像新娘。我一直安慰自己鞭执,他們只是感情好司顿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布芒粹。 她就那樣靜靜地躺著,像睡著了一般大溜。 火紅的嫁衣襯著肌膚如雪化漆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天钦奋,我揣著相機(jī)與錄音座云,去河邊找鬼。 笑死付材,一個(gè)胖子當(dāng)著我的面吹牛朦拖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播厌衔,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼璧帝,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了葵诈?” 一聲冷哼從身側(cè)響起裸弦,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤祟同,失蹤者是張志新(化名)和其女友劉穎作喘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晕城,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泞坦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了砖顷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贰锁。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖滤蝠,靈堂內(nèi)的尸體忽然破棺而出豌熄,到底是詐尸還是另有隱情,我是刑警寧澤物咳,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布锣险,位于F島的核電站,受9級(jí)特大地震影響览闰,放射性物質(zhì)發(fā)生泄漏芯肤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一压鉴、第九天 我趴在偏房一處隱蔽的房頂上張望崖咨。 院中可真熱鬧,春花似錦油吭、人聲如沸击蹲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)歌豺。三九已至芯丧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間世曾,已是汗流浹背缨恒。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留轮听,地道東北人骗露。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像血巍,于是被迫代替她去往敵國(guó)和親萧锉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

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