Elvira
Elvira

Reputation: 1430

elastic search copy_to field not filled

I'm trying to copy a main title field in Elastic Search 5.6, to an other field with: index:false, so I can use this field to match the exact value.

However. After the reindex, and performed search with _source:["exact_hoofdtitel"], the field "exact_hoofdtitel" is not filled with the value of "hoofdtitel".

PUT producten_prd_5_test
{
 "aliases": {},
 "mappings": {
   "boek": {
     "properties": {
       "hoofdtitel": {
         "type": "text",
         "copy_to": [
           "suggest-hoofdtitel", "exact_hoofdtitel"
         ]
       },
       "suggest-hoofdtitel": {
         "type": "completion",
         "analyzer": "simple",
         "preserve_separators": false,
         "preserve_position_increments": true,
         "max_input_length": 50
       },
       "exact_hoofdtitel":{
         "type":"text",
         "fields":{
           "keyword":{
             "type":"keyword",
             "index":false
           }
         }
       },
     }
   }
 },
 "settings": {
   "number_of_shards": "1",
   "number_of_replicas": "0"
 }
}


GET producten_prd_5_test/_search
{
  "_source":["hoofdtitel","exact_hoofdtitel"]
}


hits": [
      {
        "_index": "producten_prd_5_test",
        "_type": "boek",
        "_id": "9781138340671",
        "_score": 1,
        "_source": {
          "hoofdtitel": "The Nature of the Firm in the Oil Industry"
        }
      },

Upvotes: 3

Views: 2487

Answers (1)

Nikolay Vasiliev
Nikolay Vasiliev

Reputation: 6066

I believe that you can achieve what you want without copy_to. Let me show you how and why you don't need it here.

How can I make both full-text and exact match queries on the same field?

This can be done with fields mapping attribute. Basically, with the following piece of mapping:

PUT producten_prd_5_test_new
{
  "aliases": {},
  "mappings": {
    "boek": {
      "properties": {
        "hoofdtitel": {
          "type": "text", <== analysing for full text search
          "fields": {
            "keyword": {
              "type": "keyword" <== analysing for exact match
            },
            "suggest": {  
              "type": "completion",  <== analysing for suggest
              "analyzer": "simple",
              "preserve_separators": false,
              "preserve_position_increments": true,
              "max_input_length": 50
            }
          }
        }
      }
    }
  }
}

you will be telling Elasticsearch to index the same field three times: one for full-text search, one for exact match and one for suggest.

The exact search will be possible to do via a term query like this:

GET producten_prd_5_test_new/_search
{
  "query": {
    "term": {
      "hoofdtitel.keyword": "The Nature of the Firm in the Oil Industry"
    }
  }
}

Why the field exact_hoofdtitel does not appear in the returned document?

Because copy_to does not change the source:

The original _source field will not be modified to show the copied values.

It works like _all field, allowing you to concat values of multiple fields in one imaginary field and analyse it in a special way.

Does it make sense to do a copy_to to an index: false field?

With index: false the field will not be analyzed and will not be searchable (like in your example, the field exact_hoofdtitel.keyword).

It may still make sense to do so if you want to do keyword aggregations on that field:

GET producten_prd_5_test/_search
{
  "aggs": {
    "by copy to": {
      "terms": {
        "field": "exact_hoofdtitel.keyword"
      }
    }
  }
}

This will return something like:

{
  "aggregations": {
    "by copy to": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "The Nature of the Firm in the Oil Industry",
          "doc_count": 1
        }
      ]
    }
  }
}

Upvotes: 6

Related Questions