elasticsearch實戰摘錄

目錄

elasticSearch語法摘錄

準備相關:

docker啓動es

索引新數據

選擇合適的查詢類型:使用term

使用過濾器:

應用聚合:

通過ID獲取文檔:

配置es集羣

索引更新和刪除數據

查看所有索引

使用mapping來定義各種文檔

獲取目前的映射

索引一篇新的文檔

查看上面的新mapping

定義新的mapping

用於定義文檔字段的核心類型

常用字段類型的查詢

數組和多字段

使用預定義字段

更新現有的文檔

使用 /_update

使用與doc同級的upsert參數來創建不存在的修改

通過腳本來更新文檔

通過版本來實現併發控制

刪除數據

刪除文檔

搜索數據

介紹查詢和過濾器DSL

常用的基礎查詢和過濾器:

組合查詢或複合查詢

bool查詢

bool過濾器

range查詢和過濾器

prefix查詢和過濾器

wildcard通配符查詢

exists過濾器

分析數據

 

N元語法(ngram)和edge-ngram和滑動窗口

使用相關性進行搜索

使用boosting來影響文檔的得分

解釋一篇文檔不匹配的原因

使用查詢再打分來減少評分操作的性能影響(7.x似乎缺少相關屬性??)

使用function_score來定製得分(7.x引入了script_score)

合併得分

1)field_value_factor

2)script_score

3)random_score

4)衰減函數


elasticSearch語法摘錄

2020-06-21: notepad++中刪除空格換行回車等方式,ctrl+f ==> 勾選循環查找和正則表達式 ==>替換欄輸入\s 即可.

準備相關:

刪除docker鏡像 docker rmi id或標籤

使用tag爲鏡像添加標籤: docker tag 舊repostery:tag  新repostery:tag

當repostery不同,tag相同,imageID也相同的時候,使用docker rmi respostery:tag 刪除不想要的image.

查看正在運行的容器: docker ps

啓動已經停止的容器實例: docker start id 

啓動未啓動過的容器實例: docker run. 有三個參數 1) -it,以交互方式啓動;2) -p 映射內外部端口; 3) -d 以附加進程啓動

進入docker容器:docker exec -it id前3位(可以模糊查詢) /bin/bash ; 退出可以直接輸入exit

停止一個正在運行的容器: docker stop 容器ID或容器名 有一個參數 -t,給容器時間(秒)去保存自己的狀態:dcoker stop -t=20

直接立即關閉容器:docker kill 容器名ID

重啓一個容器: docker restart ID或名稱  對於正在運行的容器進行重啓就可以加-t給一個保存狀態的時間.

查看容器: docker inspect 容器名

刪除容器: docker rm -v:直接刪除容器,並解除與之關聯的卷. -l db是移除容器甲對容器乙的連接db;-f db01 db02是刪除容器db01和db02

清理臨時的沒有被使用的鏡像文件:docker image prune(慎用!)

查看層級歷史:docker history ID

docker啓動es

9200端口用於外部通信,9300用於集羣內部通信.

docker run -p 9200:9200 elasticsearch ,然後瀏覽器中調es所在ip:9200查看是否啓動成功

索引是由一個或多個被稱爲分片的數據塊組成.易於擴展

索引有分片,分片有副本,分片和副本可存在於不同的節點.當有3個節點5個分片和5個副本時:深色爲分片,淺色爲副本

一個es服務是一個節點,或者一個es進程也是一個節點.多個節點可以加入同一個集羣.默認情況下可以連接集羣中任意一個節點並訪問完整的數據集(完整的數據集不限於單個節點).

當索引一篇文檔時,系統首先根據文檔ID的散列值選擇一個主分片將該文檔發送過去,這個主分片可能位於別的節點(機器,線程).然後主分片開始同步該文檔至所有副分片.搜索該文檔時,es需要在該索引的完整分片集合中進行查找,這些分片可能是主分片也可能是副分片.

一份分片是Lucene的索引:一個包含倒排索引的文件目錄.一個es索引由多個Lucene索引組成.副分片可以在運行的時候進行添加和移除,主分片不可以.過多的分片會影響性能.

分佈式索引和搜索.索引時一旦確定文檔所在分片,接受請求的節點將文檔發送到分片所在節點.然後同步至所有副本.搜索時接受請求的節點將請求轉發到一組包含所有數據的分片(可以是不同的節點上).es使用round-robin的輪訓機制選擇可用的分片(主分片或副分片).並將搜索請求轉發過去.然後es從這些分片收集結果,將其聚集到單一的回覆返回給客戶端.

索引新數據

cURL的使用: -X此處不帶空格[GET默認可以不帶-X PUT PIST]; 單引號'ip:9200/索引/ID?pretty'

添加一個文檔的命令:

curl -XPOST -H "Content-Type:application/json" '192.168.1.103:9200/get-together/1?pretty' -d '{"name":"Elasticsearch","organizer":"chow"}'

//返回
{
  "_index" : "get-together",
  "_type" : "1",
  "_id" : "ol8p0XIBV6yKmAPNJs-g",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}
[root@localhost ~]# curl -XPUT '192.168.1.103:9200/new-index'
{"acknowledged":true,"shards_acknowledged":true,"index":"new-index"}

查看mapping的命令:

[root@localhost ~]# curl '192.168.1.103:9200/get-together/_mapping?pretty'

全文查找的 例子:這裏加不了&fields=name,location\

[root@localhost ~]# curl "192.168.1.103:9200/get-together/_search?\
q=elasticsearch\
&size=1\
&pretty"

//es7.x已經移除type

可以寫成&q=name,location:elasticsearch

[root@localhost ~]# curl "192.168.1.103:9200/get-together/_search?\
q=name:elasticsearch\
&size=1\
&pretty"

索引處可以加多個索引,用逗號隔開.也可以省略索引直接在所有索引間搜索.將不同範圍的數據構建到不同的索引裏,而不是一個大索引?

請求參數可以加"timeout=3s",設定請求在超過3秒後超時.此時只能獲得這期間查到的內容.

返回結果中的"_shards"一欄會返回成功命中的分片以及失敗的分片.即便有分片宕機,依然可以返回剩餘分片的查詢結果.

es默認限制結果數量爲10.使用size參數修改返回的數量.

使用json格式制定搜索條件:

[root@localhost ~]# curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"query":{"query_string":{"query":"Denver"}}}'

單query裏指定多條件字段的AND查詢可以這樣寫:注意query裏面的AND一定要大寫

[root@localhost ~]# curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"query":{"query_string":{"query":"name:Denver AND location_group:Denver"}}}'

選擇合適的查詢類型:使用term

curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"query":{"term":{"name":"elasticsearch"}}}'

使用過濾器:

如果對打分不感興趣,使用過濾器更快更適合緩存.使用filter要配合bool查詢.max_score項爲0.0.不會根據得分排序.

curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"query":{"bool":{"filter":{"term":{"name":"elasticsearch"}}}}}'

應用聚合:

對沒有優化或加索引的字段聚合會報錯.

[root@localhost ~]# curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_search?pretty' -d '{"aggregations":{"organizers":{"terms":{"field":"organizer"}}}}'

      "caused_by" : {
        "type" : "illegal_argument_exception",
        "reason" : "Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [organizer] in order to load field data by uninverting the inverted index. Note that this can use significant memory."

優化方式就是set fielddata=true .注意這裏是_mapping相關操作

[root@localhost ~]# curl -H "Content-Type:application/json" '192.168.1.103:9200/get-together/_mapping?pretty' -d '{"properties":{"organizer":{"type":"text","fielddata":true}}}'
{
  "acknowledged" : true
}

在此聚合,就可以了.

"aggregations" : {
    "organizers" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "lee",
          "doc_count" : 2
        },
        {
          "key" : "andy",
          "doc_count" : 1
        },
        {
          "key" : "daniel",
          "doc_count" : 1
        },
        {
          "key" : "mik",
          "doc_count" : 1
        },
        {
          "key" : "tyler",
          "doc_count" : 1
        }
      ]
    }
  }

通過ID獲取文檔:

/_doc不能少

curl '192.168.1.103:9200/get-together/_doc/1?pretty'

配置es集羣

1.elasticsearch.yml中指定集羣的名稱   cluster.name  改名稱後原有數據將不可見,不是丟失.

2.logging.yml中編輯日誌選項 cluster-name.log;超過半秒的慢搜索日誌:cluster-name_index_search_slowlog.log;超過半秒的慢索引(索引相關操作)日誌:cluster-name_index_indexing_slowlog.log.

3.在環境變量或elasticsearch.in.sh中調整內存設置.這是配置java虛擬機  在文件開始部分加ES_HEAP_SIZE=500m.默認是256MB 實際生產中如果機器只運行es,可以將heap_size設置爲最多一半的機器內存.

索引更新和刪除數據

有3種類型的字段:基本字段,數組和多元字段,預定義字段.可以用預定義字段_ttl設置過期文檔自動刪除.

查看所有索引

[root@localhost ~]# curl "192.168.1.103:9200/_cat/indices?v"
health status index                  uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   indexforputandmapping  gi0ZFKysRD6g1cO7ieTefA   1   1          1            0        4kb            4kb
yellow open   get-together           bM_WypSDQBma_mL4cHMdKA   2   1         20            0     45.2kb         45.2kb
yellow open   myindex                Fqk1gJbrTL6vyZ9eKXD0rg   1   1          0            0       208b           208b
yellow open   november_2014_invoices QEbTWlFMQJWPPWwXfss45A   1   1          0            0       208b           208b
yellow open   december_2014_invoices eMBBAX8WRKCAEAeUmZEixg   1   1          0            0       208b           208b
yellow open   new-index              iN-g0oqpQt6Qza6CmKqVtQ   1   1          0            0       208b           208b
green  open   .kibana_1              oRggM7WgRA-sN218C_WEkg   1   0          1            0      3.8kb          3.8kb

使用mapping來定義各種文檔

獲取目前的映射

curl '192.168.1.103:9200/get-together/_mapping?pretty'

索引一篇新的文檔

[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/indexforputandmapping/1?pretty' -d '{"name":"Late Night with Elasticsearch","date":"2013-10-25T19:00"}'
{
  "_index" : "indexforputandmapping",
  "_type" : "1",
  "_id" : "yV-d1nIBV6yKmAPNM89t",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

查看上面的新mapping

[root@localhost ~]# curl '192.168.1.103:9200/indexforputandmapping/_mapping?pretty'
{
  "indexforputandmapping" : {
    "mappings" : {
      "properties" : {
        "date" : {
          "type" : "date"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

定義新的mapping

定義新的字段host,類型爲text.es7.x移除了string,8之後會徹底移除.

[root@localhost ~]# curl -XPUT -H 'Content-Type:application/json' '192.168.1.103:9200/indexforputandmapping/_mapping?pretty' -d '{"properties":{"host":{"type":"text"}}}'
{
  "acknowledged" : true
}

可以每次只添加新字段,mapping會自動合併.再次查看該索引:

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/indexforputandmapping/_mapping?pretty'
{
  "indexforputandmapping" : {
    "mappings" : {
      "properties" : {
        "date" : {
          "type" : "date"
        },
        "host" : {
          "type" : "text"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

用於定義文檔字段的核心類型

請參考這篇文章: https://blog.csdn.net/Mikowoo007/article/details/106585422

7.x 有字符串類:text,keyword;

數值型:long,integer,short,byte,double,float,half_float,scaled_float;布爾型:boolean;二進制型:binary默認不存儲不搜索;

範圍類型:integer_range,float_range,date_range等,譬如 age 的類型是 integer_range, 那麼值可以是 {“gte”:20, “lte”: 40}:搜索 “term” {“age”:21} 可以搜索該值;

日期型:date 通過格式來判斷是否屬於date類型;

複雜數據類型:array 直接用[]定義,數組中的類型必須一致,可以是object對象數組;

對象類型:Object 查詢時使用點操作符指定字段名;

專用數據類型: IP,經緯度geo_point等

常用字段類型的查詢

先插一條數據

[root@localhost ~]# curl "192.168.1.103:9200/new-index/_mapping?pretty"
{
  "new-index" : {
    "mappings" : { }
  }
}

[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/1?pretty' -d '{"name":"Late Night with Elasticsearch","date":"2013-10-25T19:00"}'
{
  "_index" : "new-index",
  "_type" : "1",
  "_id" : "yl8A13IBV6yKmAPNIc-T",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

查詢.默認分詞器將所有字符轉化爲小寫,query_string的效果:會對搜索詞進行分詞,然後在text類型(也會分詞)中去匹配,詞詞之間可以不連續詞序也可以調換.match_phrase則要求(所分的詞)必須連續且順序.請參考:https://www.cnblogs.com/chenmz1995/p/10199147.html

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_search?pretty' -d '{"query":{"query_string":{"query":"late"}}}'
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "new-index",
        "_type" : "1",
        "_id" : "yl8A13IBV6yKmAPNIc-T",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "Late Night with Elasticsearch",
          "date" : "2013-10-25T19:00"
        }
      }
    ]
  }
}

對於不需要搜索的字段可以設置index爲no,以節省空間,加快索引及搜索過程.

數組和多字段

數組    :如果要索引擁有多個值的字段,將這些值放在方括號中.數組在mapping中的type是裏面數據的基本類型.

多字段:使用多字段可以對同一個字段設置不同的type及index屬性.這裏演示給tag字段加上一個不索引的配置的字段.注意配置"index":false

[root@localhost ~]# curl -XPUT -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_mapping?pretty' -d '{"properties":{"date":{"type":"date"},"name":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"tags":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256},"verbatim":{"type":"text","index":false}}}}}'    {
  "acknowledged" : true
}

再查看該索引的mapping就會發現tag字段的mapping變了

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_mapping?pretty'          {
  "new-index" : {
    "mappings" : {
      "properties" : {
        "date" : {
          "type" : "date"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "tags" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            },
            "verbatim" : {
              "type" : "text",
              "index" : false
            }
          }
        }
      }
    }
  }
}

使用預定義字段

/_cat/indices:查看所有索引

C:\Users\admin>curl localhost:9200/_cat/indices?pretty

_source:返回所有數據,如果只要返回某些字段,可以加上&_source=字段名

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_search?pretty&_source=name'
{
  "took" : 13,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "new-index",
        "_type" : "1",
        "_id" : "yl8A13IBV6yKmAPNIc-T",
        "_score" : 1.0,
        "_source" : {
          "name" : "Late Night with Elasticsearch"
        }
      },
      {
        "_index" : "new-index",
        "_type" : "1",
        "_id" : "zV9E13IBV6yKmAPNVs-r",
        "_score" : 1.0,
        "_source" : { }
      }
    ]
  }
}

還可以使用filter_path將took,timeout,_shards等過濾掉(不選即不顯示):這裏只顯示了?pretty&filter_path=hits.hits._source&_source=name

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/new-index/_search?pretty&filter_path=hits.hits._source&_source=name'
{
  "hits" : {
    "hits" : [
      {
        "_source" : {
          "name" : "Late Night with Elasticsearch"
        }
      },
      {
        "_source" : { }
      }
    ]
  }
}

更新現有的文檔

文檔的更新包括檢索文檔,處理文檔,並重新索引文檔,直至先前的文檔被覆蓋.

使用 /_update

更新前:

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/2?pretty'
{
  "_index" : "get-together",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "relationship_type" : "group",
    "name" : "Elasticsearch Denver",
    "organizer" : "Lee",
    "description" : "Get together to learn more about using Elasticsearch, the applications and neat things you can do with ES!",
    "created_on" : "2013-03-15",
    "tags" : [
      "denver",
      "elasticsearch",
      "big data",
      "lucene",
      "solr"
    ],
    "members" : [
      "Lee",
      "Mike"
    ],
    "location_group" : "Denver, Colorado, USA"
  }
}

更新時:

[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/2/_update?pretty' -d '{"doc":{"organizer":"Roy"}}'
{
  "_index" : "get-together",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 16,
  "_primary_term" : 1
}

更新後:organizer改變,_version改變

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/2?pretty'         {
  "_index" : "get-together",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 2,
  "_seq_no" : 16,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "relationship_type" : "group",
    "name" : "Elasticsearch Denver",
    "organizer" : "Roy",
    "description" : "Get together to learn more about using Elasticsearch, the applications and neat things you can do with ES!",
    "created_on" : "2013-03-15",
    "tags" : [
      "denver",
      "elasticsearch",
      "big data",
      "lucene",
      "solr"
    ],
    "members" : [
      "Lee",
      "Mike"
    ],
    "location_group" : "Denver, Colorado, USA"
  }
}

如果之前文檔不存在,那麼這裏會操作失敗並提示文檔缺失.同時也應該使用版本去避免併發修改.

使用與doc同級的upsert參數來創建不存在的修改

id爲20的文檔先前不存在,先upsert

[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/20/_update?pretty' -d '{"doc":{"organizer":"chow"},"upsert":{"name":"Elasticsearch Denver","organizer":"chow"}}'
{
  "_index" : "get-together",
  "_type" : "_doc",
  "_id" : "20",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 5,
  "_primary_term" : 1
}

再查看,已有

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/get-together/_doc/20?pretty'        {
  "_index" : "get-together",
  "_type" : "_doc",
  "_id" : "20",
  "_version" : 1,
  "_seq_no" : 5,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "Elasticsearch Denver",
    "organizer" : "chow"
  }
}

通過腳本來更新文檔

可以實現:1)改值 2)刪字段 等

默認的腳本語言是Grovvy;

腳本涉及到修改並重新索引文檔,所以使用ctx._source來引用_source, 使用ctx_source.字段名 來引用某個指定的字段;

如果涉及到變量,建議在params下作爲參數單獨定義.參數與腳本分離,這樣腳本只需要編譯一次.

修改前:

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/online-shop/shirts/1?pretty'
{
  "_index" : "online-shop",
  "_type" : "shirts",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "price" : 15
  }
}

修改中:這裏的+=後面一定要用params引出參數名

[root@localhost ~]# curl -XPOST -H 'Content-Type:application/json' '192.168.1.103:9200/online-shop/shirts/1/_update?pretty' -d '{"script":{"inline":"ctx._source.price += params.price_diff","params":{"price_diff":10}}}'
{
  "_index" : "online-shop",
  "_type" : "shirts",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

修改後:

[root@localhost ~]# curl -XGET -H 'Content-Type:application/json' '192.168.1.103:9200/online-shop/shirts/1?pretty'        {
  "_index" : "online-shop",
  "_type" : "shirts",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "price" : 25
  }
}

遇到一些語法報錯問題,參考了這篇文章: https://blog.csdn.net/sanbingyutuoniao123/article/details/79687195

向數組中添加還需要在腳本中使用add()方法.

通過版本來實現併發控制

模擬併發修改.此處改成在Kibana中調用es

POST /online-shop/shirts/1/_update
{
  "script":"Thread.sleep(5000);ctx._source.price = 2"
}
POST /online-shop/shirts/1/_update
{
  "script":"ctx._source.caption = \"Knowing Elasticsearch\""
}

樂觀鎖,假設很少出現衝突.真的出現衝突的時候就報錯.悲觀鎖則通過鎖住可能引起衝突的操作預防衝突.

此處可以設置/_update?retry_on_conflict=3讓es自動在衝突時重試.

可以設置使用外部版本:?version_type=external

刪除數據

刪除單個或部分文檔,先標記後異步刪除;刪除整個索引幾乎瞬間就能完成;還可以關閉索引

刪除文檔

根據id刪除單個文檔:也可以有版本控制

DELETE /online-shop/shirts/1

刪除查詢匹配的文檔:

Kibana的搜索

直接刪除索引:

DELETE /online-shop

關閉索引: 索引名/_close 打開索引:索引名/_open

搜索數據

關鍵詞:query,size,from,_source,sort

GET /get-together/_search
{
  "from":0,
  "size": 10,
  "sort":[{"date":"desc"}],
  "_source":{
    "includes": ["date","title"]  //可以不加includes或excludes,直接跟在_source後面
  }
}

介紹查詢和過濾器DSL

GET /get-together/_search
{
  "query":{
    "match": {
      "title": "hadoop"
    }
  }
}

term屬於過濾器.

常用的基礎查詢和過濾器:

1) query_string的用法

GET /get-together/_search
{
  "query":{
    "query_string": {
      "default_field": "description",
      "query": "nosql"
    }
  }
}

query中可以帶上Lucene的表達式,可以使用 AND OR TO 以及使用減號"-"進行結果剔除.

GET /get-together/_search
{
  "query":{
    "query_string": {
      "default_field": "description",
      "query": "(tags:search OR tags:lucene) AND created_on:[1999-01-01 TO 2001-01-01] AND -description:mongodb"
    }
  }
}

2) term查詢和term過濾器

GET /get-together/_search
{
  "query":{
    "term":{
      "tags": "elasticsearch"
    }
  }
}

term過濾:filter要配合bool使用.max_score不再評分

GET /get-together/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "tags": "elasticsearch"
        }
      }
    }
  }
}

3)terms查詢

GET /get-together/_search
{
  "query": {
    "terms": {
      "tags": [
        "elasticsearch",
        "jvm"
      ]
    }
  }
}

4) match查詢和term過濾器

match查詢是一個散列映射,包含了希望搜索的字段和字符串.match查詢 可以有多重方式,最常見的是boolean和詞組phrase.

1.布爾查詢方式: match會分詞,這裏查詢的是Elasticsearch 和 Denver

GET /get-together/_search
{
  "query": {
    "match": {
      "name": {
        "query": "Elasticsearch Denver",
        "operator": "and"  //默認是or
      }
    }
  }
}

2.詞組查詢方式 允許詞與詞之間可以有別的詞

GET /get-together/_search
{
  "query": {
    "match": {
      "name": {
        //7.x沒有type
        "query": "enterprise london"
        //7.x沒有slop
      }
    }
  }
}

還可以用詞的開頭去匹配

GET /get-together/_search
{
  "query": {
    "match": {
      "name": {
        "query": "Elasticsearch Den",
        "max_expansions": 1
      }
    }
  }
}

3.使用multi_match來匹配多個字段,注意fields數組裏的字段類型和query的類型

GET /online-shop/shirts/_search
{
  "query":{
    "multi_match": {
      "query": "haha",
      "fields": ["caption","name"]
    }
  }
}

組合查詢或複合查詢

bool查詢

GET /online-shop/shirts/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "name": "hadoop"
          }
        }
      ],
      "should": [
        {
          "term": {
            "name": "hadoop"
          }
        },
        {
          "term": {
            "name": "1"
          }
        }
      ],
      "must_not": [
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ]
    }
  }
}

bool過濾器

query不能直接跟filter,需要用bool包一層.must和should包在同一層真的沒問題嗎?

GET /online-shop/shirts/_search
{
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "name": "hadoop"
              }
            }
          ],
          "should": [
            {
              "term": {
                "name": "hadoop"
              }
            },
            {
              "term": {
                "name": "1"
              }
            }
          ],
          "must_not": [
            {
              "range": {
                "price": {
                  "gte": 10,
                  "lte": 20
                }
              }
            }
          ]
        }
      }
    }
  }
}

range查詢和過濾器

GET /online-shop/shirts/_search
{
  "query":{
    "range": {
      "FIELD": {
        "gte": 10,
        "lte": 20
      }
    }
  }
}

過濾器形式:

GET /online-shop/shirts/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "FIELD": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ]
    }
  }
}

prefix查詢和過濾器

GET /online-shop/shirts/_search
{
  "query": {
    "prefix": {
      "caption": {
        "value": "e"
      }
    }
  }
}

可用於根據輸入實時查詢,如果要帶有一定的模糊性,可以使用match_phrase_prefix

wildcard通配符查詢

*匹配任意數量字符,?匹配一個字符.?無法匹配空格.通配符出現的越早,查詢性能越低.類似的有regexp查詢.

GET /online-shop/shirts/_search
{
  "query": {
    "wildcard": {
      "caption": {
        "value": "l*n"
      }
    }
  }
}

exists過濾器

只查詢特定字段有值的文檔.

GET /get-together/_search
{
  "query": {
    "bool":{
      "filter": [
        {
          "exists": {
            "field": "tags"
          }
        }
      ]
    }
  }
}

高版本es filter的寫法改爲在bool中指定filter,並移除了missing的api(7.x已移除),可以在 bool must not 中指定exists代表不存在

 

分析數據

字符過濾->分詞->分詞過濾->索引數據

match,match_phrase會對查詞進行分詞分析.term和terms不會.

如果要對字段進行分析,在mapping的該字段下設置analyzer參數;如果不想分析,可以設置該字段的index屬性爲not_analyzed.

還可以通過fields屬性設置不同的分詞分析方式.

 

分析器包括:字符過濾器,一個單個分詞器,0或多個分詞過濾器.

關於keyword analyzer,最好是在映射中將涉及的字段設爲not_analyzed.

N元語法(ngram)和edge-ngram和滑動窗口

ngram是將一個詞進行一個字符間距的分割或多個指定字符間距的分割.可以設置min_gram和max_gram.會以min到max之間的間距分別分割字符串.可用於具有一定相似度的模糊查詢.

edge-ngram的分詞方式是始終從一側開始包含詞頭,分詞數量相對較少.可以通過設置side屬性來指定從詞尾開始分詞.

滑動窗口類似上面的分詞,但它是分詞級別的N元語法,而不像上面的那樣是字符串級別的.滑動窗口適用於查詢英語中連續的短語.

使用相關性進行搜索

詞頻和逆文檔頻率.Lucene評分公式TF-IDF基於此.

更換字段的打分方案是在mapping中字段屬性下設置similarity屬性.也可以在setting中設置更高級的配置.

使用boosting來影響文檔的得分

GET /online-shop/shirts/_search
{
  "query": {
    "boosting": {
      "positive": {
        "match": {
          "caption": "Elasticsearch"
        }
      },
      "negative": {
        "multi_match": {
          "fields": [
            "acption",
            "name"
          ],
          "query": "hadoop"
        }
      },
      "negative_boost": 0.2
    }
  }
}

boost大致是加權的作用.將所有字段的boost設置相同的值等於都沒設置.

基本所有的查詢都能設置boost,除此以外還可以通過function_score更精細的來控制boosting.

可以使用explain來解釋分值的形成.舉例如下:

GET /online-shop/shirts/_search
{
  "query": {
    "match": {
      "caption": "hadoop"
    }
  },
  "explain": true
}

解釋一篇文檔不匹配的原因

需要先知道文檔的id,然後使用/_explain進行分析.

GET /online-shop/shirts/1/_explain
{
  "query": {
    "match": {
      "caption": "java"
    }
  }
}
//返回結果
{
  "_index" : "online-shop",
  "_type" : "shirts",
  "_id" : "1",
  "matched" : false,
  "explanation" : {
    "value" : 0.0,
    "description" : "no matching term",
    "details" : [ ]
  }

使用查詢再打分來減少評分操作的性能影響(7.x似乎缺少相關屬性??)

在下列情況下打分可能會變成資源密集型的操作:

1.使用腳本來計算每篇

2.進行phrase詞組查詢.

使用function_score來定製得分(7.x引入了script_score)

GET /online-shop/shirts/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "caption": "hadoop"
        }
      },
      "functions": [
        {
          "weight": 2,  //相當於原boost * 2
          "filter": {    //在上述查詢結果中過濾出caption字段含"elasticSearch"的
            "term": {
              "caption": "elasticsearch"
            }
          }
        }
      ]
    }
  }
}

function_score查詢有一組不同的函數,每個函數可以使用另一個過濾器函數.

合併得分

上面的functions數組中可以放多個weight,每個weight的分值可以不一樣.那麼可以通過score_mode參數(multiply,sum,avg,fitst,max,min.如果沒有說明默認是multiply)來合併不同函數的得分.

還有一種是boost_mode.它控制了原始查詢的得分和函數得分是如何合併的.

1)field_value_factor

2)script_score

3)random_score

如果不想第一頁永遠展示那幾個文檔,可以設不同的seed

GET /get-together/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "description": "elasticsearch"
        }
      },
      "functions": [
        {
          "random_score": {
            "seed": 31415926535
          }
        }
      ]
    }
  },
  "size": 2
}

4)衰減函數

如果想要最近的文檔優先展示,老的文檔靠後.或者在地理位置上靠近某個點的結果增加得分,遠離的結果減少得分.可以使用這個函數.根據熱度,時間,距離進行打分.

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章