0
votes

In elastic search aggregation query I need to get all the movies watched by the user who watches the movie "Frozen". This is how my Result source

{
  "_index": "user",
  "_type": "user",
  "_id": "ovUowmUBREWOv-CU-4RT",
  "_version": 4,
  "_score": 1,
  "_source": {
    "movies": [
      "Angry birds 1",
      "PINNOCCHIO",
      "Frozen",
      "Hotel Transylvania 3"
    ],
    "user_id": 86
  }
}

This is the query I'm using.

{
  "query": {
    "match": {
      "movies": "Frozen"
    }
  },
  "size": 0,
  "aggregations": {
    "movies_like_Frozen": {
      "terms": {
        "field": "movies",
        "min_doc_count": 1
      }
    }
  }
}

The result I got in the bucket is correct, but the movie names are splits by white space like this

"buckets": [
                {
                    "key": "3",
                    "doc_count": 2
                },
                {
                    "key": "hotel",
                    "doc_count": 2
                },
                {
                    "key": "transylvania",
                    "doc_count": 2
                },
                {
                    "key": "1",
                    "doc_count": 1
                },
                {
                    "key": "angry",
                    "doc_count": 1
                },
                {
                    "key": "birds",
                    "doc_count": 1
                }
            ]

How can I get buckets with "Angry birds 1", "Hotel Transylvania 3" as result.

Please help.

1
Which Elasticsearch version you are using? - Ashwani Shakya
version number "6.2.3" - lekshmi
You need to create a mapping for text type fields, all text fields in 6.x are analyzed by default. use "index": "not_analyzed". - Ashwani Shakya
you can't store your movie name the way you are storing them right now. If you use @AshwaniShakya's approach and save them in the same way, your buckets will look like this: { "key": "Angry birds 1 PINNOCCHIO Frozen Hotel Transylvania 3", "doc_count": 1 } - Archit Saxena
Can't I store the data as a list (like I'm doing now). If no, how i need to store movies for a user - lekshmi

1 Answers

1
votes

In elasticsearch 6.x, every text field is analyzed implicitly. To override this, you need to create a mapping for text type fields as not_analyzed in an index, then insert documents in it.

In your case,

{
  "mappings": {
    "user": {
      "properties": {
        "movies": {
          "type": "text",
          "index": "not_analyzed",
          "fields": {
            "keyword": {
              "type": "text",
              "index": "not_analyzed"
            }
          }
        },
        "user_id": {
          "type": "long"
        }
      }
    }
  }
}

Hope it works.