Muhammad Hamza Ali
Muhammad Hamza Ali

Reputation: 139

how to search for tags in elasticsearch

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
        }
      }
    }
  }
}

Upvotes: 12

Views: 21688

Answers (1)

Archit Saxena
Archit Saxena

Reputation: 1547

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 type: text

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

And index your values as:

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

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"
          }
        }
      ]
    }
  }
}

Upvotes: 12

Related Questions