how to search for tags in elasticsearch

Muhammad Hamza Ali picture Muhammad Hamza Ali · Mar 30, 2017 · Viewed 12k times · Source

I am creating search for photo gallery project where photos could have upto 50 tags (just like in shutterstock and fotolia). I am creating my search in elasticsearch. I have a field with datatype keyword in elasticsearch. When query comes like "Abstract Background", I want to search for abstract and background in all the keywords of the images and sort them by their relevancy. It should not match abstr backgrou. I wrote a query like this

 "query": {
    "bool": {
      "should": [
        {
          "match": {
            "keyword": {
              "query": "abstract, background"
            }
          }
        }
      ]
    }
  }

It only works for matching single keywords. I want to match for multiple keywords and also sort them by their relevancy. Thanks

-----EDIT------

These are my mappings. Title field works fine. Category is just used for aggregations and keyword is the main field to match.

PUT /freevects
{
  "mappings": {
    "photos": {
      "properties": {
        "title": {
          "type": "text",
          "boost": 1.9,
          "analyzer": "standard"
        },
        "keyword": {
          "type": "keyword",
          "boost": 1.4
        },
        "category": {
          "type": "keyword",
          "index": false
        },
        "quality": {
          "type": "short",
          "index": false,
          "boost": 1.1
        },
        "downloads": {
          "type": "integer",
          "index": false,
          "boost": 1.1
        },
        "likes": {
          "type": "integer",
          "index": false,
          "boost": 1
        },
        "filename": {
          "type": "keyword",
          "index": false
        },
        "type": {
          "type": "keyword",
          "index": false
        },
        "free": {
          "type": "short",
          "index": false
        },
        "created": {
          "type": "date",
          "index": false
        }
      }
    }
  }
}

Answer

Archit Saxena picture Archit Saxena · Mar 30, 2017

The problem is with the mapping of keyword field. It is of type: keyword in your mapping. This doesn't tokenize your search query and the indexed values. So when you search, the terms are searched as is. Example: Searching for: "abstract, background" as you did in your question, will actually search only exact occurrences of "abstract, background" in the keyword field.

Change the mapping of keyword field to:

"keyword": {
  "type": "text",
  "boost": 1.4
}

And index your values as:

{
  "keyword": ["abstract", "background"]
}

would be my suggestion.

Reference: https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-keyword-analyzer.html

Query for searching tags:

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "keyword": "abstract"
          }
        },
        {
          "match": {
            "keyword": "background"
          }
        }
      ]
    }
  }
}

Edit: Changed type from string to text, as type string is deprecated in the newer version of ES, as pointed out by OP.