天天看點

Elasticsearch使用指南之Elasticsearch Mapping parameters(主要參數一覽)

作者簡介:《RocketMQ技術内幕》作者、中間件興趣圈微信公衆号維護者。

本文将詳細介紹Elasticsearch在建立索引映射時可指定的參數,并重點分析其含義。

1、analyzer

指定分詞器。elasticsearch是一款支援全文檢索的分布式存儲系統,對于text類型的字段,首先會使用分詞器進行分詞,然後将分詞後的詞根一個一個存儲在反向索引中,後續查詢主要是針對詞根的搜尋。

analyzer該參數可以在每個查詢、每個字段、每個索引中使用,其優先級如下(越靠前越優先):

1)字段上定義的分詞器

2)索引配置中定義的分詞器

3)預設分詞器(standard)

在查詢上下文,分詞器的查找優先為:

1)full-text query中定義的分詞器

2)定義類型映射時,字段中search_analyzer 定義的分詞器。

3)定義字段映射時analyzer定義的分詞器

4)索引中default_search中定義的分詞器。

5)索引中預設定義的分詞器

6)标準分詞器(standard)。

2、normalizer

規劃化,主要針對keyword類型,在索引該字段或查詢字段之前,可以先對原始資料進行一些簡單的處理,然後再将處理後的結果當成一個詞根存入反向索引中,舉例如下:

PUT index
{
  "settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {                                    // @1
          "type": "custom",
          "char_filter": [],
          "filter": ["lowercase", "asciifolding"]             // @2
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "properties": {
        "foo": {
          "type": "keyword",
          "normalizer": "my_normalizer"                      // @3
        }
      }
    }
  }
}           

代碼@1:首先在settings中的analysis屬性中定義normalizer。

代碼@2:設定标準化過濾器,示例中的處理器為小寫、asciifolding。

代碼@3:在定義映射時,如果字段類型為keyword,可以使用normalizer引用定義好的normalizer。

3、 boost

權重值,可以提升在查詢時的權重,對查詢相關性有直接的影響,其預設值為1.0。其影響範圍為詞根查詢(team query),對字首、範圍查詢、全文索引(match query)不生效。

注意:不建議在建立索引映射時使用boost屬性,而是在查詢時通過boost參數指定。其主要原因如下:

1)無法動态修改字段中定義的boost值,除非使用reindex指令重建索引。

2)相反,如果在查詢時指定boost值,每一個查詢都可以使用不同的boost值,靈活。

3)在索引中指定boost值,boost存儲在記錄中,進而會降低分數計算的品質。

4、coerce

是否進行類型“隐式轉換”。es最終存儲文檔的格式是字元串。

例如存在如下字段類型:

"number_one": {
   "type": "integer"
}           

聲明number_one字段的類型為數字類型,那是否允許接收“6”字元串形式的資料呢?因為在JSON中,“6”用來賦給int類型的字段,也是能接受的,預設coerce為true,表示允許這種指派,但如果coerce設定為false,此時es隻能接受不帶雙引号的數字,如果在coerce=false時,将“6”指派給number_one時會抛出類型不比對異常。

可以在建立索引時指定預設的coerce值,示例如下:

PUT my_index
{
  "settings": {
    "index.mapping.coerce": false
  },
  "mappings": {
    // 省略字段映射定義
  }
}           

5、copy_to

copy_to參數允許您建立自定義的_all字段。換句話說,多個字段的值可以複制到一個字段中例如,first_name和last_name字段可以複制到full_name字段如下:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "first_name": {
          "type": "text",
          "copy_to": "full_name" 
        },
        "last_name": {
          "type": "text",
          "copy_to": "full_name" 
        },
        "full_name": {
          "type": "text"
        }
      }
    }
  }
}           

表示字段full_name的值來自 first_name + last_name。

關于copy_to重點說明:

1)字段的複制是原始值,而不是分詞後的詞根。

2)複制字段不會包含在_souce字段中,但可以使用複制字段進行查詢。

3)同一個字段可以複制到多個字段,寫法如下:"copy_to": [ "field_1", "field_2" ]

6、 doc_values

當需要對一個字段進行排序時,es需要提取比對結果集中的排序字段值集合,然後進行排序。反向索引的資料結構對檢索來說相當高效,但對排序就不那麼擅長了。

業界對排序、聚合非常高效的資料存儲格式首推列式存儲,在elasticsearch中,doc_values就是一種列式存儲結構,預設情況下絕大多數資料類型都是開啟的,即在索引時會将字段的值(或分詞後的詞根序列)加入到反向索引中,同時也會該字段的值加入doc_values中,所有該類型的索引下該字段的值用一列存儲。

doc_values的使用示例:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "status_code": { 
          "type":       "keyword"      // 預設情況下,“doc_values”:true
        },
        "session_id": { 
          "type":       "keyword",
          "doc_values": false
        }
      }
    }
  }
}           

7、dynamic

是否允許動态的隐式增加字段。在執行index api或更新文檔API時,對于_source字段中包含一些原先未定義的字段采取的措施,根據dynamic的取值,會進行不同的操作:

1)true,預設值,表示新的字段會加入到類型映射中。

2)false,新的字段會被忽略,即不會存入_souce字段中,即不會存儲新字段,也無法通過新字段進行查詢。

3)strict,會顯示抛出異常,需要新使用put mapping api先顯示增加字段映射。

dynamic設定為false,也是可以通過put mapping api進行字段的新增,同樣put mapping api可以對dynamic值進行更新。

舉例說明:

PUT my_index/_doc/1 
{
  "username": "johnsmith",
  "name": {
    "first": "John",
    "last": "Smith"
  }
}
PUT my_index/_doc/2              // @1
{
  "username": "marywhite",
  "email": "[email protected]",
  "name": {
    "first": "Mary",
    "middle": "Alice",
    "last": "White"
  }
}
GET my_index/_mapping  // @2           

代碼@1在原有的映射下,增加了username,name.middle兩個字段,通過代碼@2擷取映射API可以得知,es已經為原本不存在的字段自動添加了類型映射定義。

注意:dynamic隻對目前層級具有限制力,例如:

PUT my_index
{
  "mappings": {
    "_doc": {
      "dynamic": false,         // @1
      "properties": {
        "user": {                    // @2
          "properties": {
            "name": {
              "type": "text"
            },
            "social_networks": {    // @3
              "dynamic": true,
              "properties": {}
            }
          }
        }
      }
    }
  }
}           

代碼@1:_doc類型的頂層不能不支援動态隐式添加字段映射。

代碼@2:但_doc的嵌套對象user對象,是支援動态隐式添加字段映射。

代碼@3:同樣對于嵌套對象social_networks,也支援動态隐式添加字段映射。

8、enabled

是否建立索引,預設情況下es會嘗試為你索引所有的字段,但有時候某些類型的字段,無需建立索引,隻是用來存儲資料即可。隻有映射類型(type)和object類型的字段可以設定enabled屬性。示例如下:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "user_id": {
          "type":  "keyword"
        },
        "last_updated": {
          "type": "date"
        },
        "session_data": { 
          "enabled": false
        }
      }
    }
  }
}

PUT my_index/_doc/session_1
{
  "user_id": "kimchy",
  "session_data": { 
    "arbitrary_object": {
      "some_array": [ "foo", "bar", { "baz": 2 } ]
    }
  },
  "last_updated": "2015-12-06T18:20:22"
}           

上述示例,es會存儲session_data對象的資料,但無法通過查詢API根據session_data中的屬性進行查詢。

同樣,可以通過put mapping api更新enabled屬性。

9、eager_global_ordinals

全局序列号,它以字典順序為每個惟一的術語保持遞增的編号。全局序号隻支援字元串類型(關鍵字和文本字段)。在關鍵字字段中,它們在預設情況下是可用的,但文本字段隻能fielddata=true時可用。doc_values(和fielddata)也有序号,是特定段(segment)和字段中所有詞根(term)的唯一編号。全局序号隻是在此之上建構的,它提供了段序号(segment ordinals)和全局序号(global ordinals)之間的映射,全局序号在整個分片中是唯一的。由于每個字段的全局序号與一個分片(shard)的所有段(segment)相關聯,是以當一個新的segment(段)變為可見時,需要完全重新建構它們。術語聚合依懶全局序号,首先在分片級别(shard)執行聚合,然後彙聚所有分片的結果(reduce)并将全局序号轉換為真正的詞根(字元串),合并後傳回聚合後的結果。預設情況下,全局序号是在搜尋時加載的,這對提高索引API的速度會非常有利。但是,如果您更加重視搜尋性能,,那麼在您計劃使用的聚合的字段上設定eager_global_ordinals,會對提高查詢效率更有幫助。

eager_global_ordinals的意思是預先加載全局序号。

其示例如下:

PUT my_index/_mapping/_doc
{
  "properties": {
    "tags": {
      "type": "keyword",
      "eager_global_ordinals": true
    }
  }
}           

10、fielddata

為了解決排序與聚合,elasticsearch提供了doc_values屬性來支援列式存儲,但doc_values不支援text字段類型。因為text字段是需要先分析(分詞),會影響doc_values列式存儲的性能。es為了支援text字段高效排序與聚合,引入了一種新的資料結構(fielddata),使用記憶體進行存儲。預設建構時機為第一次聚合查詢、排序操作時建構,主要存儲反向索引中的詞根與文檔的映射關系,聚合,排序操作在記憶體中執行。是以fielddata需要消耗大量的JVM堆記憶體。一旦fielddata加載到記憶體後,它将永久存在。通常情況下,加載fielddata是一個昂貴的操作,故預設情況下,text字段的字段預設是不開啟fielddata機制。在使用fielddata之前請慎重考慮為什麼要開啟fielddata。通常text字段用來進行全文搜尋,對于聚合、排序字段,建議使用doc_values機制。

為了節省記憶體的使用,es提供了另一項機制(fielddata_frequency_filter),允許隻加載那些詞根頻率在指定範圍(最大,小值)直接的詞根與文檔的映射關系,最大最小值可以指定為絕對值,例如數字,也可以基于百分比(百分比的計算是基于整個分段(segment),其頻率分母不是分段(segment)中所有的文檔,而是segment中該字段有值的文檔)。可以通過min_segment_size參數來指定分段中必須包含的最小文檔數量來排除小段,也就是說可以控制fielddata_frequency_filter的作用範圍是包含大于min_segment_size的文檔數量的段。

11、format

在JSON文檔中,日期表示為字元串。Elasticsearch使用一組預先配置的格式來識别和解析這些字元串,并将其解析為long類型的數值(毫秒)。

日期格式主要包括如下3種方式:

1)自定義格式

2)date mesh(已在DSL查詢API中詳解)

3)内置格式

一:自定義格式

首先可以使用java定義時間的格式,例如:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "date": {
          "type":   "date",
          "format": "yyyy-MM-dd HH:mm:ss"
        }
      }
    }
  }
}           

二:date mesh

某些API支援,已在DSL查詢API中詳細介紹過,這裡不再重複。

三:内置格式

elasticsearch為我們内置了大量的格式,如下:

  1. epoch_millis

    時間戳,機關,毫秒。

  2. epoch_second

    時間戳,機關,秒。

  3. date_optional_time

    日期必填,時間可選,其支援的格式如下:

Elasticsearch使用指南之Elasticsearch Mapping parameters(主要參數一覽)
  1. basic_date

    其格式表達式為 :yyyyMMdd

  2. basic_date_time

    其格式表達式為:yyyyMMdd'T'HHmmss.SSSZ

  3. basic_date_time_no_millis

    其格式表達式為:yyyyMMdd'T'HHmmssZ

  4. basic_ordinal_date

    4位數的年 + 3位(day of year),其格式字元串為yyyyDDD

  5. basic_ordinal_date_time

    其格式字元串為yyyyDDD'T'HHmmss.SSSZ

  6. basic_ordinal_date_time_no_millis

    其格式字元串為yyyyDDD'T'HHmmssZ

  7. basic_time

    其格式字元串為HHmmss.SSSZ

  8. basic_time_no_millis

    其格式字元串為HHmmssZ

  9. basic_t_time

    其格式字元串為'T'HHmmss.SSSZ

  10. basic_t_time_no_millis

    其格式字元串為'T'HHmmssZ

  11. basic_week_date

    其格式字元串為xxxx'W'wwe,4為年 ,然後用'W', 2位week of year(所在年裡周序号) 1位 day of week。

  12. basic_week_date_time

    其格式字元串為xxxx'W'wwe'T'HH:mm:ss.SSSZ.

  13. basic_week_date_time_no_millis

    其格式字元串為xxxx'W'wwe'T'HH:mm:ssZ.

  14. date

    其格式字元串為yyyy-MM-dd

  15. date_hour

    其格式字元串為yyyy-MM-dd'T'HH

  16. date_hour_minute

    其格式字元串為yyyy-MM-dd'T'HH:mm

  17. date_hour_minute_second

    其格式字元串為yyyy-MM-dd'T'HH:mm:ss

  18. date_hour_minute_second_fraction

    其格式字元串為yyyy-MM-dd'T'HH:mm:ss.SSS

  19. date_hour_minute_second_millis
  20. date_time
  21. date_time_no_millis
  22. hour

    其格式字元串為HH

  23. hour_minute

    其格式字元串為HH:mm

  24. hour_minute_second

    其格式字元串為HH:mm:ss

  25. hour_minute_second_fraction

    其格式字元串為HH:mm:ss.SSS

  26. hour_minute_second_millis
  27. ordinal_date

    其格式字元串為yyyy-DDD,其中DDD為 day of year。

  28. ordinal_date_time

    其格式字元串為yyyy-DDD‘T’HH:mm:ss.SSSZZ,其中DDD為 day of year。

  29. ordinal_date_time_no_millis

    其格式字元串為yyyy-DDD‘T’HH:mm:ssZZ

  30. time

    其格式字元串為HH:mm:ss.SSSZZ

  31. time_no_millis

    其格式字元串為HH:mm:ssZZ

  32. t_time

    其格式字元串為'T'HH:mm:ss.SSSZZ

  33. t_time_no_millis

    其格式字元串為'T'HH:mm:ssZZ

  34. week_date

    其格式字元串為xxxx-'W'ww-e,4位年份,ww表示week of year,e表示day of week。

  35. week_date_time

    其格式字元串為xxxx-'W'ww-e'T'HH:mm:ss.SSSZZ

  36. week_date_time_no_millis

    其格式字元串為xxxx-'W'ww-e'T'HH:mm:ssZZ

  37. weekyear

    其格式字元串為xxxx

  38. weekyear_week

    其格式字元串為xxxx-'W'ww,其中ww為week of year。

  39. weekyear_week_day

    其格式字元串為xxxx-'W'ww-e,其中ww為week of year,e為day of week。

  40. year

    其格式字元串為yyyy

  41. year_month

    其格式字元串為yyyy-MM

  42. year_month_day

    溫馨提示,日期格式時,es建議在上述格式之前加上strict_字首。

12、ignore_above

超過ignore_above設定的字元串不會被索引或存儲。對于字元串數組,将分别對每個數組元素應ignore_above,超過ignore_above的字元串元素将不會被索引或存儲。目前測試的結果為:對于字元串字元長度超過ignore_above會存儲,但不索引(也就是無法根據該值去查詢)。

其測試效果如下:

public static void create_mapping_ignore_above() {   // 建立映射
        RestHighLevelClient client = EsClient.getClient();
        try {
            CreateIndexRequest request = new CreateIndexRequest("mapping_test_ignore_above2");
            XContentBuilder mapping = XContentFactory.jsonBuilder()
                    .startObject()
                        .startObject("properties")
                            .startObject("lies")
                                .field("type", "keyword")      // 建立關鍵字段
                                .field("ignore_above", 10)     // 設定長度不能超過10
                            .endObject()
                        .endObject()
                    .endObject();
            
//            request.mapping("user", mapping_user);
            request.mapping("_doc", mapping);
            System.out.println(client.indices().create(request, RequestOptions.DEFAULT));
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            EsClient.close(client);
        }
    }
    
    public static void index_mapping_ignore_above() {  // 索引資料
        RestHighLevelClient client = EsClient.getClient();
        try {
            IndexRequest request = new IndexRequest("mapping_test_ignore_above2", "_doc");
            Map<String, Object> data = new HashMap<>();
            data.put("lies", new String[] {"dingabcdwei","huangsw","wuyanfengamdule"});
            request.source(data);
            System.out.println(client.index(request, RequestOptions.DEFAULT));
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            EsClient.close(client);
        }
    }

public static void search_ignore_above() {  // 查詢資料
        RestHighLevelClient client = EsClient.getClient();
        try {
            SearchRequest searchRequest = new SearchRequest();
            searchRequest.indices("mapping_test_ignore_above2");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(
                    // QueryBuilders.matchAllQuery()    // @1
                    // QueryBuilders.termQuery("lies", "dingabcdwei")  // @2
                    // QueryBuilders.termQuery("lies", "huangsw")      // @3
            ); 
            searchRequest.source(sourceBuilder);
            SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(result);
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            EsClient.close(client);
        }
    }           

代碼@1:首先查詢所有資料,其_souce字段的值為:"_source":{"lies":["dingabcdwei","huangsw","wuyanfengamdule"]},表名不管字元串的值是否大于ignore_above指定的值,都會存儲。

代碼@2:用超過ignore_above長度的值嘗試去搜尋,發現無法比對到記錄,表明并未加入到反向索引中。

代碼@3:用未超過ignore_above長度的值嘗試去搜尋,發現能比對到記錄。

注意:在es中,ignore_above的長度是字元的長度,而es其底層實作lucene是使用位元組進行計算的,故,如果要回報到lucnce,請注意關系。

13、ignore_malformed

試圖将錯誤的資料類型索引到字段中,預設情況下會抛出異常,并拒絕整個文檔。ignore_malformed參數,如果設定為真,允許錯誤被忽略。格式不正确的字段不建立索引,但是文檔中的其他字 段正常處理。可以建立索引時,設定index.mapping.ignore_malformed 配置項來定義索引級别的預設值,其優先級為 字段級、索引級。

14、index

定義字段是否索引,true:代表索引,false表示不索引(則無法通過該字段進行查詢),預設值為true。

  • index_options

    控制文檔添加到反向索引的額外内容,其可選擇值如下:

  1. docs:文檔編号添加到反向索引。
  2. freqs:文檔編号與通路頻率。
  3. positions:文檔編号、通路頻率、詞位置(順序性),proximity 和phrase queries 需要用到該模式。
  4. offsets:文檔編号,詞頻率,詞偏移量(開始和結束位置)和詞位置(序号),高亮顯示,需要設定為該模式。

    預設情況下,被分析的字元串(analyzed string)字段使用positions,其他字段使用docs;

15、fields

fields允許對同一索引中同名的字段進行不同的設定,舉例說明:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "city": {
          "type": "text",        // @1
          "fields": {              // @2
            "raw": { 
              "type":  "keyword"   // @3
            }
          }
        }
      }
    }
  }
}           

@1:上述映射為city字段,定義類型為text,使用全文索引。

@2:為city定義多字段,city.raw,其類型用keyword。

主要就可以用user進行全文比對,也可以用user.raw進行聚合、排序等操作。另外一種比較常用的場合是對該字段使用不同的分詞器。

16、norms

字段的評分規範,存儲該規範資訊,會提高查詢時的評分計算效率。雖然規範對計分很有用,但它也需要大量磁盤(通常是索引中每個字段的每個文檔一個位元組的順序,甚至對于沒有這個特定字段的文檔也是如此)。從這裡也可以看出,norms适合為過濾或聚合的字段。

注意,可以通過put mapping api 将norms=true更新為norms=false,但無法從false更新到true。

17、null_value

将顯示的null值替換為新定義的額值。用如下示例做一個說明:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "status_code": {
          "type":       "keyword",
          "null_value": "NULL"             // @1
        }
      }
    }
  }
}

PUT my_index/_doc/1
{
  "status_code": null                     // @2
}

PUT my_index/_doc/2
{
  "status_code": []                       // @3
}

GET my_index/_search
{
  "query": {
    "term": {
      "status_code": "NULL"               // @4
    }
  }
}           

代碼@1:為status_code字段定義“NULL”為空值null;

代碼@2:該處,存儲在status_code為 null_value中定義的值,即"NULL"

代碼@3:空數組不包含顯式null,是以不會被null_value替換。

代碼@4:該處查詢,會查詢出文檔1。其查詢結果如下:

{
    "took":4,
    "timed_out":false,
    "_shards":{
        "total":5,
        "successful":5,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":1,
        "max_score":0.2876821,
        "hits":[
            {
                "_index":"mapping_test_null_value",
                "_type":"_doc",
                "_id":"RyjGEmcB-TTORxhqI2Zn",
                "_score":0.2876821,
                "_source":{
                    "status_code":null
                }
            }
        ]
    }
}           

null_value具有如下兩個特點:

null_value需要與字段的資料類型相同。例如,一個long類型的字段不能有字元串null_value。

null_value隻會索引中的值(反向索引),無法改變_souce字段的值。

18、position_increment_gap

針對多值字段,值與值之間的間隙。舉例說明:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "names": {
          "type": "text",
          "position_increment_gap": 0      // @1
          // "position_increment_gap": 10  // @2
        }
      }
    }
  }
}

PUT my_index/_doc/1
{
    "names": [ "John Abraham", "Lincoln Smith"]
}           

names字段是個數組,也即ES中說的多值字段

當position_increment_gap=0時,es的預設使用标準分詞器,分成的詞根為:

position 0 : john

position 1 : abraham

position 2 : lincoln

position 3 : smith

當position_increment_gap = 10時,es使用預設分詞器,分成的詞根為:

position 0 : john

position 11 : lincoln 這是第二個詞,等于上一個詞的position + position_increment_gap。

position 12 : smith

針對如下下查詢:

GET my_index/_search
{
    "query": {
        "match_phrase": {
            "names": "Abraham Lincoln" 
        }
    }
}           

針對position_increment_gap=0時,能比對上文檔,如果position_increment_gap=10,則無法比對到文檔,因為abraham與lincoln的位置相差10,如果要能比對到該文檔,需要在查詢時設定slop=10,該參數在前面的DSL查詢部分已詳細介紹過。

19、properties

為映射類型建立字段定義。

20、search_analyzer

通常,在索引時和搜尋時應用相同的分析器,以確定查詢中的術語與反向索引中的術語具有相同的格式,如果想要在搜尋時使用與存儲時不同的分詞器,則使用search_analyzer屬性指定,通常用于ES實作即時搜尋(edge_ngram)。

21、similarity

指定相似度算法,其可選值:

  1. BM25

    目前版本的預設值,使用BM25算法。

  2. classic

    使用TF/IDF算法,曾經是es,lucene的預設相似度算法。

  3. boolean

    一個簡單的布爾相似度,當不需要全文排序時使用,并且分數應該隻基于查詢條件是否比對。布爾相似度為術語提供了一個與它們的查詢boost相等的分數。

22、store

預設情況下,字段值被索引以使其可搜尋,但它們不存儲。這意味着可以查詢字段,但無法檢索原始字段值。通常這并不重要。字段值已經是_source字段的一部分,該字段預設存儲。如果您隻想檢索單個字段或幾個字段的值,而不是整個_source,那麼這可以通過字段過濾上下文(source filting context來實作,在某些情況下,存儲字段是有意義的。例如,如果您有一個包含标題、日期和非常大的内容字段的文檔,您可能隻想檢索标題和日期,而不需要從大型_source字段中提取這些字段,es還提供了另外一種提取部分字段的方法,stored_fields,stored_fields過濾,隻支援字段的store定義為ture,該部分内容已經在Elasticsearch Doc api時,_souce過濾部分詳細介紹過,這裡不過多介紹。

23、term_vector

term_vector包含分析過程産生的術語的資訊,包括:

  1. 術語清單。
  2. 每一項的位置(或順序)。
  3. 開始和結束字元偏移量。

    term_vector可取值:

  • no

    不存儲term_vector資訊,預設值。

  • yes

    隻存儲字段中的值。

  • with_positions

    存儲字段中的值與位置資訊。

  • with_offsets

    存儲字段中的值、偏移量

  • with_positions_offsets

    存儲字段中的值、位置、偏移量資訊。