1. 程式人生 > >Elasticsearch Java API 的使用(11)—優化索引建立之mapping設定

Elasticsearch Java API 的使用(11)—優化索引建立之mapping設定

優化索引建立

一、_all

all欄位是把所有其它欄位中的值,以空格為分隔符組成一個大字串,然後被分析和索引,但是不儲存,也就是說它能被查詢,但不能被取回顯示。
_all欄位預設是關閉的,如果要開啟_all欄位,索引增大是不言而喻的。_all欄位開啟適用於不指定搜尋某一個欄位,根據關鍵詞,搜尋整個文件內容。

開啟_all欄位的方法,mapping中的配置如下:

//開啟_all
{
   "yourtype": {
      "_all": {
         "enabled": true
      },
      "properties": {
            ... 
      }
   }
}

//通過在欄位中指定某個欄位是否包含在_all中
{ "yourtype": { "properties": { "field1": { "type": "string", "include_in_all": false }, "field2": { "type": "string", "include_in_all": true } } } }

如果要把欄位原始值儲存,要設定store屬性為true,這樣索引會更大,需要根據需求使用。下面給出測試程式碼。

//設定mapping,這裡設定所有欄位都儲存在_all中並且儲存原始值
PUT test/test/_mapping
{
   "test": {
      "_all": {
         "enabled": true,
         "store": true
      }
   }
}

//插入文件
POST test/test/1
{
    "title":"我是中國人",
    "content":"熱愛共產黨"
}

//對_all欄位進行搜尋並高亮
POST test/_search
{
   "fields": ["_all"], 
   "query": {
      "match"
: { "_all": "中國人" } }, "highlight": { "fields": { "_all": {} } } } //返回結果 { "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 0.15342641, "hits": [ { "_index": "test", "_type": "test", "_id": "1", "_score": 0.15342641, "_all": "我是中國人 熱愛共產黨 ", "highlight": { "_all": [ "我是<em>中國人</em> 熱愛共產黨 " ] } } ] } } //Elasticsearch中的query_string和simple_query_string預設就是查詢_all欄位 GET test/_search { "query": { "query_string": { "query": "共產黨" } } }

與此同時,_all能讓你在不知道要查詢的內容是屬於哪個具體欄位的情況下進行搜尋,例如:

PUT my_index/user/1 
{
  "first_name":    "John",
  "last_name":     "Smith",
  "date_of_birth": "1970-10-24"
}

GET my_index/_search
{
  "query": {
    "match": {
      "_all": "john smith 1970"
    }
  }
}

_all欄位的內容為:”john smith 1970 10 24”

_all欄位其實就是一個字串型別的欄位,與其它普通字串欄位有相同的引數,包括:analyzer, term_vectors, index_options, and store。

_all欄位在查詢時佔用更多的CPU和佔用更多的磁碟空間,如果確實不需要它可以完全的關閉它或者基於每欄位定製。

二、_source

_source欄位預設是儲存的, 什麼情況下不用保_source欄位?如果某個欄位內容非常多,業務裡面只需要能對該欄位進行搜尋,最後返回文件id,檢視文件內容會再次到mysql或者hbase中取資料,把大欄位的內容存在Elasticsearch中只會增大索引,這一點文件數量越大結果越明顯,如果一條文件節省幾KB,放大到億萬級的量結果也是非常可觀的。

source的總結:

  1. ES預設檢索只會返回ID,如果在{“enabled”:false}情況下,你需通過根據這個ID去去倒排索引中去取每個Field資料,效率不高。而反之,在{“enabled”:true}的情況下可以根據ID直接檢索對應source JSON的欄位,不用去倒排索引去按Field取資料。
  2. 儘管_source非常有用, 但它確實會佔用索引的儲存空間, 所以也可以禁用(enabled false)、啟用狀態的壓縮策略(compress)。
    壓縮的策略有兩類:

    • compress:是否進行壓縮,建議一般情況下將其設為true 。
    • “includes” : [“author”, “name”], “excludes” : [“sex”] 。

如果想要關閉_source欄位,在mapping中的設定如下:

{
    "yourtype":{
        "_source":{
            "includes":["field1","field2"]
        },
        "properties": {
            ... 
        }
    }
}

如果只想儲存某幾個欄位的原始值到Elasticsearch,可以通過incudes引數來設定,在mapping中的設定如下:

{
    "yourtype":{
        "_source":{
            "includes":["field1","field2"]
        },
        "properties": {
            ... 
        }
    }
}

同樣,可以通過excludes引數排除某些欄位:

{
    "yourtype":{
        "_source":{
            "excludes":["field1","field2"]
        },
        "properties": {
            ... 
        }
    }
}

當設定mapping,禁用_source,返回結果的查詢結果中不會再返回文件原始內容、

//_source禁用
PUT test/test/_mapping
{
   "test": {
      "_source": {
         "enabled": false
      }
   }
}

//寫入一條文件
POST test/test/1
{
    "title":"我是中國人",
    "content":"熱愛共產黨"
}

//查詢文件——搜尋關鍵詞”中國人”
GET test/_search
{
    "query": {
        "match": {
           "title": "中國人"
        }
    }
}

//搜尋關鍵詞”中國人”:
GET test/_search
{
    "query": {
        "match": {
           "title": "中國人"
        }
    }
}
{
   "took": 9,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0.30685282,
      "hits": [
         {
            "_index": "test",
            "_type": "test",
            "_id": "1",
            "_score": 0.30685282
         }
      ]
   }
}
三、index和store

index和store屬性實在欄位內進行設定的,下面給出一個例子,設定test索引不儲存_source,title欄位索引但不分析,欄位原始值寫入索引,content欄位為預設屬性。

store的總結:

  1. 在不手動設定store的情況下,預設值為no。
  2. 如果在{“store”:yes}的情況下,ES會對該欄位單獨儲存倒排索引,每次根據ID檢索的時候,會多走一次IO來從倒排索引取資料。而如果_source enabled 情況下,ES可以直接根據Client類來解析_source JSON,只需一次IO就將所有欄位都檢索出來了。
  3. {“store”:yes}既然這麼費力不討好,但是仍然有兩個應用場景:
    • 文件很長,檢索所有文件或者儲存所有文件、獲取所有field的代價比較大。
    • 僅僅針對某幾個欄位進行re-index的時候

程式碼如下:

//設定index和store
PUT test/test/_mapping
{
   "test": {
      "_source": {
         "enabled": false
      },
      "properties": {
         "title": {
            "type": "string",
            "index": "not_analyzed",
            "store": "true"
         },
         "content": {
            "type": "string"
         }
      }
   }
}

//對title欄位進行搜尋並高亮
GET test/_search
{
    "query": {
        "match": {
           "title": "我是中國人"
        }
    },
   "highlight": {
      "fields": {
         "title": {}
      }
   }
}

//返回結果
{
   "took": 6,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0.30685282,
      "hits": [
         {
            "_index": "test",
            "_type": "test",
            "_id": "1",
            "_score": 0.30685282,
            "highlight": {
               "title": [
                  "<em>我是中國人</em>"
               ]
            }
         }
      ]
   }
}

從返回結果中可以看到,雖然沒有儲存title欄位到_source, 但是依然可以實現搜尋高亮,store和source一樣有儲存原始文件的功能。

source和store的對比總結
_source\store yes no
enabled store為yes的欄位從倒排索引裡檢索,浪費IO次數 所有欄位根據Client類解析實現儲存的JSON串,僅需一次IO
disabled store為yes的欄位從倒排索引裡檢索,其他欄位能檢索不能展示 所有欄位只能檢索,不能展示
Java APi設定示例
public class CreateIndex {

    public static void main(String[] args) {
        try {
            /* 建立客戶端 */
            // client startup
            // 設定叢集名稱
            Settings settings = Settings.builder()
                                .put("cluster.name","elsearch")
                                .put("client.transport.sniff", true)
                                .build();
            // 建立client
            TransportClient client = new 
                            PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress
                (InetAddress.getByName("10.122.4.71"), 9300));

            //建立索引
            client.admin().indices()
                .prepareCreate("pointdata2").execute().actionGet();

            //建立索引結構
            XContentBuilder builder = null;
            builder = XContentFactory.jsonBuilder()
                .startObject()
                    .startObject("pointdata2")
                        .startObject("_all")
                            //關閉_all欄位
                            .field("enabled", false)
                        .endObject()
                        .startObject("_source")
                            //關閉_source欄位
                            .field("enabled", false)
                        .endObject()
                        //properties:列出了文件中可能包含的每個欄位的對映
                        .startObject("properties")
                            .startObject("pointid")
                                .field("type", "string")
                                .field("index", "not_analyzed")
                                .field("store", true)
                            .endObject()
                            .startObject("pointvalue")
                                .field("type", "string")
                                .field("index", "not_analyzed")
                            .endObject()
                            .startObject("inputtime")
                                .field("type", "date")
                                .field("format", "yyyy-MM-dd HH:mm:ss")
                                .field("index", "not_analyzed")
                            .endObject()
                        .endObject()
                    .endObject()
                .endObject();

            PutMappingRequest mapping = Requests
                                .putMappingRequest("pointdata2")
                                .type("pointdata2")
                                .source(builder);
            client.admin().indices().putMapping(mapping).actionGet();
            System.out.println("建立成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

相關推薦

Elasticsearch Java API 的使用11優化索引建立mapping設定

優化索引建立 一、_all all欄位是把所有其它欄位中的值,以空格為分隔符組成一個大字串,然後被分析和索引,但是不儲存,也就是說它能被查詢,但不能被取回顯示。 _all欄位預設是關閉的,如果要開啟_all欄位,索引增大是不言而喻的。_all欄位開啟適

ElasticSearch原始碼解析索引建立

我們先來看看索引建立的事例程式碼: Directory directory = FSDirectory.getDirectory("/tmp/testindex"); // Use standard analyzer Analyzer analyzer = new

zabbix的Java API

strong 走了 .html image catch 是我 後來 resp 登錄密碼   上文說了,我是對zabbix做第二次開發的小白,既然要對zabbix做第二次開發又是小白,那麽就得來研究zabbix提供的相關API了。 於是我在zabbix網站各種找,終於在下面網

Java API

height val 類型 highlight pic bool 包裝 大寫 clas 數組高級以及Arrays(掌握) 1、排序 2、查找 3、Arrays 工具類 Integer(掌握) 1、為了讓基本類型的數據進行更多的操作

java基礎11、面向對象--接口

-- java font size .com span ont spa 技術分享 面向對象--接口 java基礎(11)、面向對象--接口

JAVA基礎11---成員變數和區域性變數

變數的分類: 按照變數宣告的位置(作用的範圍):     成員變數: 宣告在類的內部,方法的外部的變數,稱為成員變數                區域性變數:宣告在方

Java併發11- 有關執行緒池的10個問題

引言 在日常開發中,執行緒池是使用非常頻繁的一種技術,無論是服務端多執行緒接收使用者請求,還是客戶端多執行緒處理資料,都會用到執行緒池技術,那麼全面的瞭解執行緒池的使用、背後的實現原理以及合理的優化執行緒池的大小等都是非常有必要的。這篇文章會通過對一系列的問題的解答來講解執行緒池的基本功能以及背後的原理,

zookeeper java api2

    這裡介紹其他的API對zookeeper的操作。 同步方式獲取子節點資料 public static void getChildrenSync() throws KeeperException, InterruptedException {

zookeeper java api1

1 Zookeeper安裝以及啟動     這裡我已經進行了安裝,並且啟動了Zookeeper。埠是2182 2 Zookeeper config tickTime=2000 initLimit=10 syncLimit=5 dataDir=D://zook

Elasticsearch 通關教程索引對映Mapping問題

資料庫建表的時候,我們的DDL語句一般都會指定每個欄位的儲存型別,例如:varchar,int,datetime等等,目的很明確,就是更精確的儲存資料,防止資料型別格式混亂。 CREATE TABLE `shop_` ( `id_` varchar(36) NOT NULL COMMENT 'id',

Elasticsearch 通關教程索引別名Aliases問題

業務問題 業務需求是不斷變化迭代的,也許我們之前寫的某個業務邏輯在下個版本就變化了,我們可能需要修改原來的設計,例如資料庫可能需要新增一個欄位或刪減一個欄位,而在搜尋中也會發生這件事,即使你認為現在的索引設計已經很完美了,在生產環境中,還是有可能需要做一些修改的,需要新增對映欄位或者需要修改欄位型別等等。

Python基礎11_python模塊time模塊、rando模塊、hashlib、os模塊

路徑 固定 val 登錄密碼 rand getcwd ges ble sun 一、模塊 1、什麽是模塊:一個模塊就是一個包含了python定義和聲明的文件,文件名就是模塊名字加上.py的後綴   模塊的本質:模塊的本質是一個py文件 2、模塊分為三類:1)內置模塊;2)第三

Java學習7:同步問題生產者與消費者的問題

con runnable pop pre 標記 this auth style about 生產者生產饅頭,消費者消費饅頭。一個籃子,生產者往籃子中放饅頭,消費者從籃子中取饅頭。 /** * 這是一個籃子類 * * @author xcx * @time 2017

Java學習面向對象封裝

所有 成對 main 將不 同時 執行順序 編譯失敗 sta sin 封 裝(面向對象特征之一):是指隱藏對象的屬性和實現細節,僅對外提供公共訪問方式。 好處:將變化隔離;便於使用;提高重用性;安全性。 封裝原則:將不需要對外提供的內容都隱藏起來,把屬性都隱藏,提供公共方法

啃碎併發11:記憶體模型重排序

0 前言 在很多情況下,訪問一個程式變數(物件例項欄位,類靜態欄位和陣列元素)可能會使用不同的順序執行,而不是程式語義所指定的順序執行。具體幾種情況,如下: 編譯器 能夠自由的以優化的名義去改變指令順序; 在特定的環境下,處理器 可能會次序顛倒的執行指令; 資料可能在 暫存器、處

機器學習 優化演算法利器梯度下降Gradient Descend

理解:機器學習各種演算法的求解最終出來的幾乎都是求解最優模型引數的優化問題。 前言        在優化問題領域有些很多優秀思想和演算法,從約束條件分類 分為無約束條件的優化和有約束條件的優化問題,有約束條

經驗分享11linux常用命令文字替換

linux常用命令之文字替換 1 vi vi test_file :%s/h/h1/g 註釋:全文替換,將h替換為h1 :1,4s/h/h1/g 註釋:將第1行到第4行的h替換為h1 :%s/\n/,/g 註釋:將換行符替換為, 2 sed s

Java+Selenium7】---- 元素定位詳細解析

    上篇文章介紹到了元素定位以及元素定位的八種方法,本篇詳細介紹這八種元素定位的使用方法。1. id 定位     name 如果把頁面上看元素看作一個人的話,如果我們想找一個人如何去找,那麼這個人一定有其別於其它人的“屬性”,如他的身份證號一定和別人不一樣,他的名字和別

ASP.NET Web API:安全驗證使用摘要認證(digest authentication)

在前一篇文章中,主要討論了使用HTTP基本認證的方法,因為HTTP基本認證的方式決定了它在安全性方面存在很大的問題,所以接下來看看另一種驗證的方式:digest authentication,即摘要認證。 系列文章列表 摘要認證原理 在基本認證的方式中,主要的安全問題來自於使用者資訊的明文傳輸,而

ASP.NET Web API:安全驗證使用HTTP基本認證

在前一篇文章ASP.NET Web API(一):使用初探,GET和POST資料中,我們初步接觸了微軟的REST API: Web API。 我們在接觸了Web API的後就立馬發現了有安全驗證的需求,所以這篇文章我們先來討論下安全驗證一個最簡單的方法:使用HTTP基本