Query Dsl
先準備測試數據,es有提供有關批量執行的方式:_bulk
參考:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
但是在postman中插入式異常,所以暫時使用單條插入的方式
PUT localhost:9200/movies/movie/1
{
"title": "The Godfather",
"director": "Francis Ford Coppola",
"year": 1972,
"genres": ["Crime", "Drama"]
}
PUT localhost:9200/movies/movie/2
{
"title": "Lawrence of Arabia",
"director": "David Lean",
"year": 1962,
"genres": ["Adventure", "Biography", "Drama"]
}
PUT localhost:9200/movies/movie/3
{
"title": "To Kill a Mockingbird",
"director": "Robert Mulligan",
"year": 1962,
"genres": ["Crime", "Drama", "Mystery"]
}
PUT localhost:9200/movies/movie/4
{
"title": "Apocalypse Now",
"director": "Francis Ford Coppola",
"year": 1979,
"genres": ["Drama", "War"]
}
PUT localhost:9200/movies/movie/5
{
"title": "Apocalypse Now",
"director": "Francis Ford Coppola",
"year": 1979,
"genres": ["Drama", "War"]
}
PUT localhost:9200/movies/movie/6
{
"title": "Apocalypse Now",
"director": "Francis Ford Coppola",
"year": 1979,
"genres": ["Drama", "War"]
}
數據插入完畢,可以使用全文查詢驗證一下
POST localhost:9200/_search
{
"query":{
"match_all":{}
}
}
查詢"genres"字段含有"Drama"的movie
POST localhost:9200/_search
{
"query":{
"bool":{
"must":[
{"match":{"genres":"Drama"}}
]
}
}
}
"match":{"genres":"Drama"} 子句表示"genres"字段包含"Drama"內容,"match"可有多個
查詢結果
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 5,
"max_score": 0.2876821,
"hits": [
{
"_index": "movies",
"_type": "movie",
"_id": "1",
"_score": 0.2876821,
"_source": {
"title": "The Godfather",
"director": "Francis Ford Coppola",
"year": 1972,
"genres": [
"Crime",
"Drama"
]
}
},
{
"_index": "movies",
"_type": "movie",
"_id": "3",
"_score": 0.2876821,
"_source": {
"title": "To Kill a Mockingbird",
"director": "Robert Mulligan",
"year": 1962,
"genres": [
"Crime",
"Drama",
"Mystery"
]
}
},
{
"_index": "movies",
"_type": "movie",
"_id": "4",
"_score": 0.14874382,
"_source": {
"title": "Apocalypse Now",
"director": "Francis Ford Coppola",
"year": 1979,
"genres": [
"Drama",
"War"
]
}
},
{
"_index": "movies",
"_type": "movie",
"_id": "2",
"_score": 0.12703528,
"_source": {
"title": "Lawrence of Arabia",
"director": "David Lean",
"year": 1962,
"genres": [
"Adventure",
"Biography",
"Drama"
]
}
},
{
"_index": "movies",
"_type": "movie",
"_id": "6",
"_score": 0.12703528,
"_source": {
"title": "The Assassination of Jesse James by the Coward Robert Ford",
"director": "Andrew Dominik",
"year": 2007,
"genres": [
"Biography",
"Crime",
"Drama"
]
}
}
]
}
}
可以看到一共五個結果,並且"genres"字段中都包含了"Drama"內容
如果我們需要對查詢出的5個內容進行進一步的過濾,就需要用到"filter"子句了
例如:查詢"genres"字段含有"Drama"的movie,過濾出結果中"year"字段爲 1962 的movie
POST localhost:9200/_search
{
"query":{
"bool":{
"must":[
{"match":{"genres":"Drama"}}
],
"filter":[
{"term":{"year":1962}}
]
}
}
}
查詢結果:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0.2876821,
"hits": [{
"_index": "movies",
"_type": "movie",
"_id": "3",
"_score": 0.2876821,
"_source": {
"title": "To Kill a Mockingbird",
"director": "Robert Mulligan",
"year": 1962,
"genres": ["Crime", "Drama", "Mystery"]
}
}, {
"_index": "movies",
"_type": "movie",
"_id": "2",
"_score": 0.12703528,
"_source": {
"title": "Lawrence of Arabia",
"director": "David Lean",
"year": 1962,
"genres": ["Adventure", "Biography", "Drama"]
}
}]
}
}
可以看到,結果只剩倆條了,並且這倆條的記錄的"year"字段都爲 1962
從官方文檔中得知"term"子句的功能是某字段精確匹配指定值,例如"term":{"year":1962}
可是我在查詢例如:"term":{"director":"David Lean"}時,沒有匹配數據,希望有人能告知我這是什麼原因。
當然,es也提供了範圍過濾,使用的是"range"子句,例如:
POST localhost:9200/_search
{
"query":{
"bool":{
"must":[
{"match":{"genres":"Drama"}}
],
"filter":[
{
"range":{
"year":{"gt":2000}
}
}
]
}
}
}
這條"range":{"year":{"gt":2000}}子句的意思爲,過濾出結果中"year"字段大於 2000 的內容
結果爲:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.12703528,
"hits": [
{
"_index": "movies",
"_type": "movie",
"_id": "6",
"_score": 0.12703528,
"_source": {
"title": "The Assassination of Jesse James by the Coward Robert Ford",
"director": "Andrew Dominik",
"year": 2007,
"genres": [
"Biography",
"Crime",
"Drama"
]
}
}
]
}
}
"match_phrase"子句查詢:
POST localhost:9200/_search
{
"query":{
"match_phrase":{
"title":{
"query":"Lawrence,Arabia",
"slop" : 1
}
}
}
}
"match_phrase"官方文檔的解釋爲短語匹配查詢,但是個人對這個子句沒太用明白
上面的事例中主要注意"slop"字段,它表示"query"字段以","分割的倆個短語中間最多可以間隔的單詞個數
查詢結果爲:
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1.6103166,
"hits": [
{
"_index": "movies",
"_type": "movie",
"_id": "2",
"_score": 1.6103166,
"_source": {
"title": "Lawrence of Arabia",
"director": "David Lean",
"year": 1962,
"genres": [
"Adventure",
"Biography",
"Drama"
]
}
}
]
}
}
可以看到查詢結果的"title"字段中的"Lawrence"和"Arabia"中間間隔了一個短語"of"
"match_phrase_prefix"短語前綴匹配查詢
POST localhost:9200/_search
{
"query":{
"match_phrase_prefix":{"title":{"query":"Mock"}}}}和"match_phrase"不同的一點在於,"match_phrase_prefix"只需"title"字段中含有"Mock"開頭的短語即可成功匹配
結果爲:
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "movies",
"_type": "movie",
"_id": "3",
"_score": 0.2876821,
"_source": {
"title": "To Kill a Mockingbird",
"director": "Robert Mulligan",
"year": 1962,
"genres": [
"Crime",
"Drama",
"Mystery"
]
}
}
]
}
}
官方文檔中該子句還可以包含"max_expansions"字段,經過一番測試並沒有發現其作用,希望有人能夠指教一下。
"multi_match"多字段匹配查詢
POST localhost:9200/_search
{
"query":{
"multi_match":{
"query":"Ford",
"fields":["title","director^3"]
}
}
}
"multi_match"用於多字段匹配查詢,使用"fields"來指定要匹配哪些字段
結果:
{
"took": 17,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 2.634553,
"hits": [
{
"_index": "movies",
"_type": "movie",
"_id": "4",
"_score": 2.634553,
"_source": {
"title": "Apocalypse Now",
"director": "Francis Ford Coppola",
"year": 1979,
"genres": [
"Drama",
"War"
]
}
},
{
"_index": "movies",
"_type": "movie",
"_id": "1",
"_score": 0.8630463,
"_source": {
"title": "The Godfather",
"director": "Francis Ford Coppola",
"year": 1972,
"genres": [
"Crime",
"Drama"
]
}
},
{
"_index": "movies",
"_type": "movie",
"_id": "6",
"_score": 0.69607234,
"_source": {
"title": "The Assassination of Jesse James by the Coward Robert Ford",
"director": "Andrew Dominik",
"year": 2007,
"genres": [
"Biography",
"Crime",
"Drama"
]
}
}
]
}
}
查詢結果中,"title"、"director"任意一個字段中包含"Ford"短語即可成功匹配
"director^3"官方文檔解釋爲該字段爲3倍的重要,其效果很明顯,"director"字段匹配成功的都排在前面