0

I am using Elasticsearch 7.6 and indexing a list of keywords with the following mapping definition:

"keywords" : {
  "type" : "text",
  "analyzer": "std_folded",
  "store": true,
  "fields": {
    "keyword": {
      "type": "keyword"
    }
  }
},

As you can see, the name of the field is keywords which will be given a list of words. Also, I defined keywords.keyword as the keyword type.

Is it possible to assign some value (a score) with each word? I am hoping to retrieve the value in my script query later.

halfer
  • 19,824
  • 17
  • 99
  • 186
kee
  • 10,969
  • 24
  • 107
  • 168
  • Note that we prefer a technical style of writing here. We gently discourage greetings, hope-you-can-helps, thanks, advance thanks, notes of appreciation, regards, kind regards, signatures, please-can-you-helps, chatty material and abbreviated txtspk, pleading, how long you've been stuck, voting advice, meta commentary, etc. Just explain your problem, and show what you've tried, what you expected, and what actually happened. – halfer Apr 07 '20 at 11:34

1 Answers1

1

Background

So if it was not with each word but to assign a specific value(score as in your case)for each field, you could have used something similar to index-time boost which is deprecated from 5.0.

If I understood, you can have multiple values for your keywords field like foo, bar and baz belongs to the same document. and you want to give all of the different scores like foo:1, bar:2 and baz:3, that's the score or boost on-field value, not on the field.

Solution: using nested data-type you can solve this.

Working example:

Index def

{
  "mappings": {
    "properties": {
      "keywords": {
        "type": "nested" --> note this
      }
    }
  }
}

Index sample doc

{
  "keywords" : [
    {
      "keyword" : "foo",
      "score" :  1
    },
    {
      "keyword" : "bar",
      "score" :  2
    },
    {
        "keyword" : "baz",
        "score" : 3
    }
  ]
}

Search query to fetch docs having foo and score 1

{
    "query": {
        "nested": {
            "path": "keywords",
            "query": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "keywords.keyword": "foo"
                            }
                        },
                        {
                            "match": {
                                "keywords.score": 1
                            }
                        }
                    ]
                }
            },
            "inner_hits": { --> notice this, it would bring inner doc `foo:1`

            }
        }
    }
}

Search result

 "hits": [
      {
        "_index": "nested",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.9808291,
        "_source": {
          "keywords": [
            {
              "keyword": "foo",
              "score": 1
            },
            {
              "keyword": "bar",
              "score": 2
            },
            {
              "keyword": "baz",
              "score": 3
            }
          ]
        },
        "inner_hits": {
          "keywords": {
            "hits": {
              "total": {
                "value": 1,
                "relation": "eq"
              },
              "max_score": 1.9808291,
              "hits": [
                {
                  "_index": "nested",
                  "_type": "_doc",
                  "_id": "1",
                  "_nested": {
                    "field": "keywords",
                    "offset": 0
                  },
                  "_score": 1.9808291, --> your expected result in inner hits
                  "_source": {
                    "keyword": "foo",
                    "score": 1
                  }
                }
              ]
Amit
  • 30,756
  • 6
  • 57
  • 88