1. 程式人生 > 實用技巧 >elasticsearch mapping對映屬性_source、_all、store和index

elasticsearch mapping對映屬性_source、_all、store和index

1. _source配置

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

{
    "yourtype":{
        "_source":{
            "enabled":false
        },
        
"properties": { ... } } }

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

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

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

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

示例:

# 首先建立一個索引
PUT test

# 設定mapping,禁用_source:
PUT test/test/_mapping
{
   "test": {
      "_source": {
         "enabled": false
      }
   }
}

# 寫入一條文件:
POST test
/test/1 { "title":"我是中國人", "content":"熱愛共.產黨" #敏感詞 } # 搜尋關鍵詞”中國人”: 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 } ] } }

從返回結果中可以看到,搜到了一條文件,但是禁用_source以後查詢結果中不會再返回文件原始內容。(注,測試基於ELasticsearch 2.3.3,配置檔案中已預設指定ik分詞。)

2. _all配置

_all欄位預設是關閉的,如果要開啟_all欄位,索引增大是不言而喻的。_all欄位開啟適用於不指定搜尋某一個欄位,根據關鍵詞,搜尋整個文件內容。
開啟_all欄位的方法和_source類似,mapping中的配置如下:

{
   "yourtype": {
      "_all": {
         "enabled": true
      },
      "properties": {
            ... 
      }
   }
}

也可以通過在欄位中指定某個欄位是否包含在_all中:

{
   "yourtype": {
      "properties": {
         "field1": {
             "type": "string",
             "include_in_all": false
          },
          "field2": {
             "type": "string",
             "include_in_all": true
          }
      }
   }
}

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

DELETE  test
PUT test

設定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_stringsimple_query_string預設就是查詢_all欄位,示例如下:

GET test/_search
{
    "query": {
        "query_string": {
           "query": "共.產黨"
        }
    }
}

3.indexstore配置

indexstore屬性實在欄位內進行設定的,下面給出一個例子,設定test索引不儲存_source,title段索引但不分析,欄位原始值寫入索引,content欄位為預設屬性,程式碼如下:

DELETE  test
PUT test
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, 但是依然可以實現搜尋高亮。