Elasticsearch查詢規(guī)則(一)match和term

es種有兩種查詢模式,一種是像傳遞URL參數(shù)一樣去傳遞查詢語句把鉴,被稱為簡單搜索或查詢字符串(query string)搜索故黑,比如

GET /megacorp/employee/_search //查詢?nèi)繂T工
GET /megacorp/employee/_search?q=last_name:Smith //查詢last_name為Smith的員工

另外一種是通過DSL語句來進行查詢儿咱,被稱為DSL查詢(Query DSL),DSL是Elasticsearch提供的一種豐富且靈活的查詢語言,該語言以json請求體的形式出現(xiàn)场晶,通過restful請求與Elasticsearch進行交互混埠,本文主要講DSL查詢的一些常用規(guī)則,在介紹之前诗轻,我們先簡單插入一個測試用的小例子(假設(shè)我們已經(jīng)有了一個elasticsearch測試環(huán)境且裝好了分詞插件, 如果需要查看如何安裝中文環(huán)境钳宪,可瀏覽我的另一篇文章Elasticsearch中文搜索環(huán)境搭建)。

 $curl -XPOST http://localhost:9200/index/doc/1 -d'{"content":"美國留給伊拉克的是個爛攤子嗎","title":"標題","tags":["美國","伊拉克","爛攤子"]}'
 $curl -XPOST http://localhost:9200/index/doc/2 -d'{"content":"中國是世界上人口最多的國家","title":"中國","tags":["中國","人口"]}'
 $curl -XPOST http://localhost:9200/index/doc/3 -d'{"content":"同一個世界同一個夢想","title":"北京奧運","tags":["和平"]}'
 $curl -XPOST http://localhost:9200/index/doc/4 -d'{"content":"杭州是一個美麗的城市,歡迎來到杭州","title":"宣傳","tags":["旅游","城市"]}'

檢查一下我們的數(shù)據(jù)是否導(dǎo)入成功

$curl -XGET http://localhost:9200/index/doc/_search
{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":4,"max_score":1.0,"hits":[{"_index":"index","_type":"doc","_id":"2","_score":1.0,"_source":{"content":"中國是世界上人口最多的國家","title":"中國","tags":["中國","人口"]}},{"_index":"index","_type":"doc","_id":"4","_score":1.0,"_source":{"content":"杭州是一個美麗的城市,歡迎來到杭州","title":"宣傳","tags":["旅游","城市"]}},{"_index":"index","_type":"doc","_id":"1","_score":1.0,"_source":{"content":"美國留給伊拉克的是個爛攤子嗎","title":"標題","tags":["美國","伊拉克","爛攤子"]}},{"_index":"index","_type":"doc","_id":"3","_score":1.0,"_source":{"content":"同一個世界同一個夢想","title":"北京奧運","tags":["和平"]}}]}}

ok扳炬,導(dǎo)入成功吏颖,接下來利用這些數(shù)據(jù)逐步介紹各種常用查詢

term查詢

term是代表完全匹配,也就是精確查詢恨樟,搜索前不會再對搜索詞進行分詞侦高,所以我們的搜索詞必須是文檔分詞集合中的一個。比如說我們要找標題為北京奧運的所有文檔

$curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
  "query":{
    "term":{
        "title":"北京奧運"
    }
  }
}'

將會得到如下結(jié)果

{
    "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
    "total": 1,
    "max_score": 0.92055845,
    "hits": [
     {
        "_index": "index",
        "_type": "doc",
        "_id": "3",
        "_score": 0.92055845,
        "_source": {
           "content": "同一個世界同一個夢想",
           "title": "北京奧運",
           "tags": [
               "和平"
            ]
        }
      }
    ]
  }
}

搜索title包含北京或者奧運的厌杜,結(jié)果也一樣奉呛,但是如果你搜索詞為京奧,或者北京奧這樣的,那么搜索結(jié)果將為空

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
      "total" : 5,
      "successful" : 5,
      "failed" : 0
  },
  "hits" : {
      "total" : 0,
      "max_score" : null,
      "hits" : [ ]
  }
}

這是因為在對文檔建立索引時夯尽,會將北京奧運分詞為北京瞧壮,奧運北京奧運匙握,只要搜索詞為這三個之一咆槽,都可以將這篇文章搜索出來,而京奧北京奧并不在分詞集合里圈纺,所以無法搜索到該文檔秦忿。
如果對于某個字段,你想精確匹配蛾娶,即搜索什么詞匹配什么詞灯谣,類似sql中的=操作,比如只能通過北京奧運搜索到文檔3而不想讓北京奧運也搜索到蛔琅,那么胎许,你可以在建立索引階段指定該字段為"index": "not_analyzed",此時,elasticsearch將不會對該字段的值進行分詞操作罗售,只保留全文字索引辜窑。比如本例子中的tags字段,我在建立索引時設(shè)置了"index": "not_analyzed", 搜索時,不管是指定tags為寨躁,還是穆碎,都無法將第一條結(jié)果搜索出來

$curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
  "query":{
    "term":{
        "tags":"美"
    }
  }
}'

搜索結(jié)果:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
      "total" : 5,
      "successful" : 5,
      "failed" : 0
  },
  "hits" : {
      "total" : 0,
      "max_score" : null,
      "hits" : [ ]
  }
}

而全詞美國卻可以

$curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
  "query":{
    "term":{
        "tags":"美國"
    }
  }
}'

搜索結(jié)果:

{
    "took" : 2,
    "timed_out" : false,
    "_shards" : {
        "total" : 5,
        "successful" : 5,
        "failed" : 0
    },
    "hits" : {
        "total" : 1,
        "max_score" : 0.30685282,
        "hits" : [ {
            "_index" : "index",
            "_type" : "doc",
            "_id" : "1",
            "_score" : 0.30685282,
            "_source" : {
                  "content" : "美國留給伊拉克的是個爛攤子嗎",
                  "title" : "標題",
                  "tags" : [ "美國", "伊拉克", "爛攤子" ]
            }
      } ]
  }
}

match類查詢

match查詢會先對搜索詞進行分詞,分詞完畢后再逐個對分詞結(jié)果進行匹配,因此相比于term的精確搜索职恳,match是分詞匹配搜索,match搜索還有兩個相似功能的變種所禀,一個是match_phrase谜悟,一個是multi_match,接下來詳細介紹一下

match

前面提到match搜索會先對搜索詞進行分詞北秽,對于最基本的match搜索來說,只要搜索詞的分詞集合中的一個或多個存在于文檔中即可最筒,例如贺氓,當我們搜索中國杭州,搜索詞會先分詞為中國杭州,只要文檔中包含搜索杭州任意一個詞床蜘,都會被搜索到

$curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
    "query": {
        "match": {
            "content": "中國杭州"
        }
    }
}'

文檔3正文中有杭州辙培,文檔2中有中國,因此搜索結(jié)果有兩個邢锯,文檔3中杭州出現(xiàn)兩次扬蕊,所以排在前面,結(jié)果如下:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
      "total" : 2,
      "max_score" : 0.99999994,
      "hits" : [ {
            "_index" : "index",
            "_type" : "doc",
            "_id" : "4",
            "_score" : 0.99999994,
            "_source" : {
                 "content" : "杭州是一個美麗的城市,歡迎來到杭州",
                "title" : "宣傳",
                "tags" : [ "旅游", "城市" ]
            }
       }, {
            "_index" : "index",
            "_type" : "doc",
            "_id" : "2",
            "_score" : 0.8838835,
            "_source" : {
                  "content" : "中國是世界上人口最多的國家",
                  "title" : "中國",
                  "tags" : [ "中國", "人口" ]
            }
       } ]
    }
}

同樣的丹擎,我們用match的方式搜索中國世界尾抑,那么,文檔2(含有中國世界)和文檔3(含有世界都會被搜索出來)蒂培。如果我們僅僅想搜索中國世界都包含的文檔該怎么辦呢再愈?
其實,對于match搜索护戳,可以按照分詞后的分詞集合的or或者and進行匹配翎冲,默認為or,這也是為什么我們看到前面的搜索都是只要有一個分詞出現(xiàn)在文檔中就會被搜索出來媳荒,同樣的抗悍,如果我們希望是所有分詞都要出現(xiàn),那只要把匹配模式改成and就行了

curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
    "query": {
        "match": {
            "content": {
                "query": "中國世界",
                "operator": "and"
            }
        }
    }
}'

如上所示钳枕,查詢時將operator設(shè)置為and缴渊,此時,就只會搜索到既包含中國鱼炒,也包含世界的文檔了(因返回的字段較多疟暖,后面搜索結(jié)果只展示_source中的內(nèi)容)

"_source" : {
    "content" : "中國是世界上人口最多的國家",
    "title" : "中國",
    "tags" : [ "中國", "人口" ]
}
match_phrase

match_phrase為按短語搜索,這個可能先用英文來解釋會直觀一點(中文分詞后其實已經(jīng)是一個一個有具體意思的詞語)田柔。英文中以空格分詞俐巴,因此分詞后是一個個的單詞,當想搜索類似hope so這樣的短語時硬爆,你或許并不想將一些只含有hope的文檔搜索出來欣舵,也不想將一些類似I hope ×××. So ××這樣的搜索出來,此時缀磕,就可以用match_phrase缘圈。
match_phrase的搜索方式和match類似劣光,先對搜索詞建立索引,并要求所有分詞必須在文檔中出現(xiàn)(像不像operator為and的match查詢)糟把,除此之外绢涡,還必須滿足分詞在文檔中出現(xiàn)的順序和搜索詞中一致且各搜索詞之間必須緊鄰,因此match_phrase也可以叫做緊鄰搜索遣疯。
所以雄可,當我們搜美國留給

curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
  "query": {
    "match_phrase": {
        "content": "美國留給"
    }
  }
}'

能搜出文檔美國留給伊拉克的是個爛攤子嗎

    "_source" : {
        "content" : "美國留給伊拉克的是個爛攤子嗎",
        "title" : "標題",
        "tags" : [ "美國", "伊拉克", "爛攤子" ]
    }

但是我們搜索留給美國美國伊拉克時,卻沒有搜索結(jié)果缠犀,因為一個順序不對数苫,一個不是緊鄰(隔著留給)。
緊鄰對于匹配度要求較高辨液,為了減小精度增加可操作性虐急,引入了slop參數(shù)。該參數(shù)可以指定相隔多少個詞仍被算作匹配成功滔迈。如下止吁,

curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
    "query": {
        "match_phrase": {
            "content": {
                "query": "美國伊拉克",
                "slop": "1"
            }
        }
    }
}'

當我們將slop設(shè)置為1時,文檔1已能被搜索到燎悍。

  "_source" : {
    "content" : "美國留給伊拉克的是個爛攤子嗎",
    "title" : "標題",
    "tags" : [ "美國", "伊拉克", "爛攤子" ]
  }

需要注意的是赏殃,當slop的值過大時(超出文檔總分詞數(shù)),那么分詞數(shù)據(jù)將可以是隨意的间涵,即跟operator為and的match查詢效果一樣仁热。比如我們查詢

curl -XGET http://localhost:9200/index/doc/_search?pretty -d 
'{
    "query": {
        "match_phrase": {
            "content": {
                "query": "伊拉克美國",
                "slop": "12"
            }
        }
    }
}'

將會得到與上面一樣的結(jié)果

multi_match

當我們想對多個字段進行匹配,其中一個字段包含分詞就被文檔就被搜索到時勾哩,可以用multi_match,這一部分內(nèi)容我們后面再講

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抗蠢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子思劳,更是在濱河造成了極大的恐慌迅矛,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件潜叛,死亡現(xiàn)場離奇詭異秽褒,居然都是意外死亡,警方通過查閱死者的電腦和手機威兜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門销斟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人椒舵,你說我怎么就攤上這事蚂踊。” “怎么了笔宿?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵犁钟,是天一觀的道長棱诱。 經(jīng)常有香客問我,道長涝动,這世上最難降的妖魔是什么迈勋? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮醋粟,結(jié)果婚禮上靡菇,老公的妹妹穿的比我還像新娘。我一直安慰自己昔穴,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布提前。 她就那樣靜靜地躺著吗货,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狈网。 梳的紋絲不亂的頭發(fā)上宙搬,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音拓哺,去河邊找鬼勇垛。 笑死,一個胖子當著我的面吹牛士鸥,可吹牛的內(nèi)容都是我干的闲孤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼烤礁,長吁一口氣:“原來是場噩夢啊……” “哼讼积!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脚仔,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤勤众,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鲤脏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體们颜,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年猎醇,在試婚紗的時候發(fā)現(xiàn)自己被綠了窥突。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡硫嘶,死狀恐怖波岛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情音半,我是刑警寧澤则拷,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布贡蓖,位于F島的核電站,受9級特大地震影響煌茬,放射性物質(zhì)發(fā)生泄漏斥铺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一坛善、第九天 我趴在偏房一處隱蔽的房頂上張望晾蜘。 院中可真熱鬧,春花似錦眠屎、人聲如沸剔交。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岖常。三九已至,卻和暖如春葫督,著一層夾襖步出監(jiān)牢的瞬間竭鞍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工橄镜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留偎快,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓洽胶,卻偏偏與公主長得像晒夹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子姊氓,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

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

  • es種有兩種查詢模式惋戏,一種是像傳遞URL參數(shù)一樣去傳遞查詢語句,被稱為簡單搜索或查詢字符串(query strin...
    會武功的蚊子閱讀 541評論 1 3
  • 博客原文一博客原文二 翻譯作品他膳,水平有限响逢,如有錯誤,煩請留言指正棕孙。原文請見 官網(wǎng)英文文檔 起步 Elasticse...
    rabbitGYK閱讀 3,228評論 0 68
  • Solr&ElasticSearch原理及應(yīng)用 一舔亭、綜述 搜索 http://baike.baidu.com/it...
    樓外樓V閱讀 7,254評論 1 17
  • 我們的公司是一家印刷企業(yè),屬于傳統(tǒng)行業(yè)蟀俊,所以我就對我近一年來的投標過程中出現(xiàn)的一些情況做一個小總結(jié)钦铺。我把它分為四個...
    葉小濤閱讀 2,644評論 0 0
  • 平谷游(二) 京東平谷初游逛,仙桃溶洞美名揚肢预。 野菜...
    璋哥說事閱讀 1,125評論 0 1