Elasticsearch 理解mapping中的store屬性


默認情況下,對字段值進行索引以使其可搜索,但不存儲它們 (store)。 這意味着可以查詢該字段,但是無法檢索原始字段值。在這里我們必須理解的一點是: 如果一個字段的mapping中含有store屬性為true,那么有一個單獨的存儲空間為這個字段做存儲,而且這個存儲是獨立於_source的存儲的。它具有更快的查詢。存儲該字段會占用磁盤空間。如果需要從文檔中提取(即在腳本中和聚合),它會幫助減少計算。在聚合時,具有store屬性的字段會比不具有這個屬性的字段快。 此選項的可能值為false和true。

通常這無關緊要。 該字段值已經是_source字段的一部分,默認情況下已存儲。 如果您只想檢索單個字段或幾個字段的值,而不是整個_source的值,則可以使用source filtering來實現。

在某些情況下,存儲字段可能很有意義。 例如,如果您有一個帶有標題,日期和很大的內容字段的文檔,則可能只想檢索標題和日期,而不必從較大的_source字段中提取這些字段。

接下來我們還是通過一個具體的例子來解釋這個,雖然上面的描述有點繞口。

首先我們來創建一個叫做my_index的索引:

PUT my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "store": true 
      },
      "date": {
        "type": "date",
        "store": true 
      },
      "content": {
        "type": "text"
      }
    }
  }
}

在上面的mapping中,我們把title及date字段里的store屬性設置為true,表明有一個單獨的index fragement是為它們而配備的,並存儲它們的值。我們來寫入一個文檔到my_index索引中:

PUT my_index/_doc/1
{
  "title": "Some short title",
  "date": "2015-01-01",
  "content": "A very long content field..."
}

接下來,我們來做一個搜索:

GET my_index/_search

顯示的結果是:

  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "title" : "Some short title",
          "date" : "2015-01-01",
          "content" : "A very long content field..."
        }
      }
    ]
  }

在上面我們可以在_source中看到這個文檔的title,date及content字段。

我們可以通過source filtering的方法提前我們想要的字段:

GET my_index/_search
{
  "_source": ["title", "date"]
}

顯示的結果是:

  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "date" : "2015-01-01",
          "title" : "Some short title"
        }
      }
    ]
  }

顯然上面的結果顯示我們想要的字段date及title是可以從_source里獲取的。

我們也可以通過如下的方法來獲取這兩個字段的值:

GET my_index/_search
{
  "stored_fields": [
    "title",
    "date"
  ]
}

返回的結果是:

  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "fields" : {
          "date" : [
            "2015-01-01T00:00:00.000Z"
          ],
          "title" : [
            "Some short title"
          ]
        }
      }
    ]
  }

在上面,我們可以看出來在fields里有一個date及title的數組返回查詢的結果。

也許我們很多人想知道到底這個store到底有什么用途呢?如果都能從_source里得到字段的值。

有一種就是我們在開頭我們已經說明的情況:我們有時候並不想存下所有的字段在_source里,因為該字段的內容很大,或者我們根本就不想存_source,但是有些字段,我們還是想要獲取它們的內容。那么在這種情況下,我們就可以使用store來實現。

我們還是用一個例子來說明。首先創建一個叫做my_index1的索引:

PUT my_index1
{
  "mappings": {
    "_source": {
      "enabled": false
    },
    "properties": {
      "title": {
        "type": "text",
        "store": true
      },
      "date": {
        "type": "date",
        "store": true
      },
      "content": {
        "type": "text",
        "store": false
      }
    }
  }
}

因為我們認為content字段的內容可能會很大,那么我不想存這個字段。在上面,我們也把_source的enabled開關設置為false,表明將不存儲任何的source字段。接下來寫入一個文檔到my_index1里去:

PUT my_index1/_doc/1
{
  "title": "Some short title",
  "date": "2015-01-01",
  "content": "A very long content field..."
}

同樣我們來做一個搜索:

GET my_index1/_search
{
  "query": {
    "match": {
      "content": "content"
    }
  }
}

我們可以看到搜索的結果:

  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "my_index1",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821
      }
    ]
  }

在這次的顯示中,我們沒有看到_source字段,這是因為我們已經把它給disabled了。但是我們可以通過如下的方法來獲取那些store 字段:

GET my_index1/_search
{
  "stored_fields": [
    "title",
    "date"
  ],
  "query": {
    "match": {
      "content": "content"
    }
  }
}

返回結果是:

  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "my_index1",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "fields" : {
          "date" : [
            "2015-01-01T00:00:00.000Z"
          ],
          "title" : [
            "Some short title"
          ]
        }
      }
    ]
  }

我們可以在返回結果里查看到date及title的值。

可以合理地存儲字段的另一種情況是,對於那些未出現在_source字段(例如copy_to字段)中的字段。您可以參閱我的另外一篇文章“如何使用Elasticsearch中的copy_to來提高搜索效率”。

如果你想了解更多關於Elasticsearch的存儲,可以閱讀文章“Elasticsearch:inverted index,doc_values及source”。

參考:

  1. https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-store.html
  2. https://stackoverflow.com/questions/17103047/why-do-i-need-storeyes-in-elasticsearch

版權聲明:本文為CSDN博主「Elastic 中國社區官方博客」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/UbuntuTouch/article/details/103810863


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM