ElasticSearch7.3學習(二十)—-採用restful風格查詢詳解

1、Query DSL入門

1.1 DSL

DSL:Domain Specified Language,特定領域的語言。es特有的搜索語言,可在請求體中攜帶搜索條件,功能強大。

查詢全部 

GET /book/_search
{
  "query": { "match_all": {} }
}

排序 

GET /book/_search 
{
    "query" : {
        "match" : {
            "name" : " java"
        }
    },
    "sort": [
        { "price": "desc" }
    ]
}

分頁查詢

GET  /book/_search 
{
  "query": { "match_all": {} },
  "from": 0,
  "size": 1
}

指定返回字段 

GET /book/_search 
{
  "query": { "match_all": {} },
  "_source": ["name", "studymodel"]
}

通過組合以上各種類型查詢,實現複雜查詢。

1.2 Query DSL語法

{
    QUERY_NAME: {
        ARGUMENT: VALUE,
        ARGUMENT: VALUE,...
    }
}
{
    QUERY_NAME: {
        FIELD_NAME: {
            ARGUMENT: VALUE,
            ARGUMENT: VALUE,...
        }
    }
}
GET /test_index/_search 
{
  "query": {
    "match": {
      "test_field": "test"
    }
  }
}

1.3 組合多個搜索條件

搜索需求:

title字段必須包含elasticsearch,content可以包含elasticsearch也可以不包含,author_id必須不為111

初始數據:

POST /website/_doc/1
{
  "title": "my hadoop article",
  "content": "hadoop is very bad",
  "author_id": 111
}

POST /website/_doc/2
{
  "title": "my elasticsearch  article",
  "content": "es is very bad",
  "author_id": 112
}
POST /website/_doc/3
{
  "title": "my elasticsearch article",
  "content": "es is very goods",
  "author_id": 111
}

搜索:

GET /website/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "elasticsearch"
          }
        }
      ],
      "should": [
        {
          "match": {
            "content": "elasticsearch"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "author_id": 111
          }
        }
      ]
    }
  }
}

返回:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.47000363,
    "hits" : [
      {
        "_index" : "website",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.47000363,
        "_source" : {
          "title" : "my elasticsearch  article",
          "content" : "es is very bad",
          "author_id" : 112
        }
      }
    ]
  }
}

再次查詢一個更複雜的搜索需求,例如如下sql語句,採用ElasticSearch來實現。

select * from test_index where name='tom' or (hired =true and (personality ='good' and rude != true ))

ES語句如下:

GET /test_index/_search
{
    "query": {
            "bool": {
                "must": { "match":{ "name": "tom" }},
                "should": [
                    { "match":{ "hired": true }},
                    { "bool": {
                        "must":{ "match": { "personality": "good" }},
                        "must_not": { "match": { "rude": true }}
                    }}
                ],
                "minimum_should_match": 1
            }
    }
}

2、full-text search 全文檢索

2.1 全文檢索

首先創建book索引

PUT /book/
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "description": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "studymodel": {
        "type": "keyword"
      },
      "price": {
        "type": "double"
      },
      "timestamp": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      },
      "pic": {
        "type": "text",
        "index": false
      }
    }
  }
}

插入數據

PUT /book/_doc/1
{
  "name": "Bootstrap開發",
  "description": "Bootstrap是由Twitter推出的一個前台頁面開發css框架,是一個非常流行的開發框架,此框架集成了多種頁面效果。此開發框架包含了大量的CSS、JS程序代碼,可以幫助開發者(尤其是不擅長css頁面開發的程序人員)輕鬆的實現一個css,不受瀏覽器限制的精美界面css效果。",
  "studymodel": "201002",
  "price": 38.6,
  "timestamp": "2019-08-25 19:11:35",
  "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  "tags": [
    "bootstrap",
    "dev"
  ]
}

PUT /book/_doc/2
{
  "name": "java編程思想",
  "description": "java語言是世界第一編程語言,在軟件開發領域使用人數最多。",
  "studymodel": "201001",
  "price": 68.6,
  "timestamp": "2019-08-25 19:11:35",
  "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  "tags": [
    "java",
    "dev"
  ]
}

PUT /book/_doc/3
{
  "name": "spring開發基礎",
  "description": "spring 在java領域非常流行,java程序員都在用。",
  "studymodel": "201001",
  "price": 88.6,
  "timestamp": "2019-08-24 19:11:35",
  "pic": "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
  "tags": [
    "spring",
    "java"
  ]
}

先簡單的搜索一下,搜索description中包含java程序員的數據

GET /book/_search
{
  "query": {
    "match": {
      "description": "java程序員"
    }
  }
}

結果如下

{
  "took" : 257,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 2.137549,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 2.137549,
        "_source" : {
          "name" : "spring開發基礎",
          "description" : "spring 在java領域非常流行,java程序員都在用。",
          "studymodel" : "201001",
          "price" : 88.6,
          "timestamp" : "2019-08-24 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "spring",
            "java"
          ]
        }
      },
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.57961315,
        "_source" : {
          "name" : "java編程思想",
          "description" : "java語言是世界第一編程語言,在軟件開發領域使用人數最多。",
          "studymodel" : "201001",
          "price" : 68.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "java",
            "dev"
          ]
        }
      }
    ]
  }
}

2.2 _score簡單介紹

對於上面的搜索結果來進行一個簡單的結果分析

1、建立索引時, description字段 term 倒排索引

關鍵詞 文檔
java 2,3
程序員 3

2、搜索時,直接找description中含有java的文檔 2,3,並且3號文檔含有兩個java字段,一個程序員,所以得分高,排在前面。2號文檔含有一個java,排在後面。

這裡只是簡單的介紹一下_score這個字段的作用,更詳細的後續會介紹。

3、DSL 語法練習

3.1 match_all

GET /book/_search
{
    "query": {
        "match_all": {}
    }
}

結果:

查看代碼
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "Bootstrap開發",
          "description" : "Bootstrap是由Twitter推出的一個前台頁面開發css框架,是一個非常流行的開發框架,此框架集成了多種頁面效果。此開發框架包含了大量的CSS、JS程序代碼,可以幫助開發者(尤其是不擅長css頁面開發的程序人員)輕鬆的實現一個css,不受瀏覽器限制的精美界面css效果。",
          "studymodel" : "201002",
          "price" : 38.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "bootstrap",
            "dev"
          ]
        }
      },
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "java編程思想",
          "description" : "java語言是世界第一編程語言,在軟件開發領域使用人數最多。",
          "studymodel" : "201001",
          "price" : 68.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "java",
            "dev"
          ]
        }
      },
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "spring開發基礎",
          "description" : "spring 在java領域非常流行,java程序員都在用。",
          "studymodel" : "201001",
          "price" : 88.6,
          "timestamp" : "2019-08-24 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "spring",
            "java"
          ]
        }
      }
    ]
  }
}

3.2 match

GET /book/_search
{
    "query": { 
        "match": { 
            "description": "java程序員"
        }
    }
}

結果:

查看代碼
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 2.137549,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 2.137549,
        "_source" : {
          "name" : "spring開發基礎",
          "description" : "spring 在java領域非常流行,java程序員都在用。",
          "studymodel" : "201001",
          "price" : 88.6,
          "timestamp" : "2019-08-24 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "spring",
            "java"
          ]
        }
      },
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.57961315,
        "_source" : {
          "name" : "java編程思想",
          "description" : "java語言是世界第一編程語言,在軟件開發領域使用人數最多。",
          "studymodel" : "201001",
          "price" : 68.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "java",
            "dev"
          ]
        }
      }
    ]
  }
}

3.3 multi_match

GET /book/_search
{
  "query": {
    "multi_match": {
      "query": "java程序員",
      "fields": [
        "name"
      ]
    }
  }
}

結果:

查看代碼
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.9331132,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.9331132,
        "_source" : {
          "name" : "java編程思想",
          "description" : "java語言是世界第一編程語言,在軟件開發領域使用人數最多。",
          "studymodel" : "201001",
          "price" : 68.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "java",
            "dev"
          ]
        }
      }
    ]
  }
}

3.4 range query 範圍查詢

gt 大於 gte 大於等於

GET /book/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 80,
        "lte": 90
      }
    }
  }
}

結果:

查看代碼
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "spring開發基礎",
          "description" : "spring 在java領域非常流行,java程序員都在用。",
          "studymodel" : "201001",
          "price" : 88.6,
          "timestamp" : "2019-08-24 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "spring",
            "java"
          ]
        }
      }
    ]
  }
}

3.5 term query

字段為keyword時,存儲和搜索都不分詞

GET /book/_search
{
  "query": {
    "term": {
      "description": "java程序員"
    }
  }
}

結果:

查看代碼
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

3.6 terms query

GET /book/_search
{
  "query": {
    "terms": {
      "tag": [
        "search",
        "full_text",
        "nosql"
      ]
    }
  }
}

結果:

查看代碼
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

3.7 exist query 查詢有某些字段值的文檔

GET /book/_search
{
    "query": {
        "exists": {
            "field": "join_date"
        }
    }
}

結果:

查看代碼
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

3.8 Fuzzy query 模糊查詢

返回包含與搜索詞類似的詞的文檔,該詞由Levenshtein編輯距離度量。

包括以下幾種情況:

  • 更改角色(box→fox)

  • 刪除字符(aple→apple)

  • 插入字符(sick→sic)

  • 調換兩個相鄰字符(ACT→CAT)

GET /book/_search
{
  "query": {
    "fuzzy": {
      "description": {
        "value": "jave"
      }
    }
  }
}

結果:

查看代碼
{
  "took" : 78,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.59524715,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 0.59524715,
        "_source" : {
          "name" : "spring開發基礎",
          "description" : "spring 在java領域非常流行,java程序員都在用。",
          "studymodel" : "201001",
          "price" : 88.6,
          "timestamp" : "2019-08-24 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "spring",
            "java"
          ]
        }
      },
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.43470988,
        "_source" : {
          "name" : "java編程思想",
          "description" : "java語言是世界第一編程語言,在軟件開發領域使用人數最多。",
          "studymodel" : "201001",
          "price" : 68.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "java",
            "dev"
          ]
        }
      }
    ]
  }
}

3.9 IDs

查詢id

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

結果:

查看代碼
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "Bootstrap開發",
          "description" : "Bootstrap是由Twitter推出的一個前台頁面開發css框架,是一個非常流行的開發框架,此框架集成了多種頁面效果。此開發框架包含了大量的CSS、JS程序代碼,可以幫助開發者(尤其是不擅長css頁面開發的程序人員)輕鬆的實現一個css,不受瀏覽器限制的精美界面css效果。",
          "studymodel" : "201002",
          "price" : 38.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "bootstrap",
            "dev"
          ]
        }
      }
    ]
  }
}

3.10 prefix 前綴查詢

GET /book/_search
{
  "query": {
    "prefix": {
      "description": {
        "value": "spring"
      }
    }
  }
}

結果:

查看代碼
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "spring開發基礎",
          "description" : "spring 在java領域非常流行,java程序員都在用。",
          "studymodel" : "201001",
          "price" : 88.6,
          "timestamp" : "2019-08-24 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "spring",
            "java"
          ]
        }
      }
    ]
  }
}

3.11 regexp query 正則查詢

以j開頭,以a結尾 .*一個或多個

GET /book/_search
{
  "query": {
    "regexp": {
      "description": {
        "value": "j.*a",
        "flags": "ALL",
        "max_determinized_states": 10000,
        "rewrite": "constant_score"
      }
    }
  }
}

結果:

查看代碼

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "java編程思想",
          "description" : "java語言是世界第一編程語言,在軟件開發領域使用人數最多。",
          "studymodel" : "201001",
          "price" : 68.6,
          "timestamp" : "2019-08-25 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "java",
            "dev"
          ]
        }
      },
      {
        "_index" : "book",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "spring開發基礎",
          "description" : "spring 在java領域非常流行,java程序員都在用。",
          "studymodel" : "201001",
          "price" : 88.6,
          "timestamp" : "2019-08-24 19:11:35",
          "pic" : "group1/M00/00/00/wKhlQFs6RCeAY0pHAAJx5ZjNDEM428.jpg",
          "tags" : [
            "spring",
            "java"
          ]
        }
      }
    ]
  }
}