2

How to search through multiple fields with elasticsearch? I've tried many queries but none of them worked out. I want the search to be case insensitive and one field is more important than the other. My query looks like this:

const eQuery = {
    query: {
        query_string: {
            query: `*SOME_CONTENT_HERE*`,
            fields: ['title^3', 'description'],
            default_operator: 'OR',
        },
    },
}
esClient.search(
    {
        index: 'movies',
        body: eQuery,
    },
    function(error, response) {
    },
)

Mapping looks like this:

{
    mappings: {
        my_index_type: {
            dynamic_templates: [{ string: { mapping: { type: 'keyword' }, match_mapping_type: 'string' } }],
            properties: {
                created_at: { type: 'long' },
                description: { type: 'keyword' },
                title: { type: 'keyword' },
                url: { type: 'keyword' },
            },
        },
        _default_: {
            dynamic_templates: [{ string: { mapping: { type: 'keyword' }, match_mapping_type: 'string' } }],
        },
    },
}
6
  • 1
    you should also write the error you are getting Commented Mar 14, 2018 at 16:11
  • I'm not getting any error. Just an empty response - unfortunately. Commented Mar 14, 2018 at 16:12
  • 1
    oh in that case, you should post your mappings and the exact query that is failing. Also, it would be great if you show the document from your ES index, that you expect to be returned. Commented Mar 14, 2018 at 16:14
  • So I found out that the problem is in query being case sensitive. I don't know how to make it case insensitive Commented Mar 14, 2018 at 16:25
  • 1
    the mapping for your index should point out the problem. If you use the standard analyzer on both the fields, you should be fine because it lowercases both the indexed values and the incoming query Commented Mar 14, 2018 at 16:28

1 Answer 1

2

The problem is the type: keyword in your mapping for fields description and title. Keyword type fields are not analyzed i.e they store the indexed data exactly like it was sent to elastic. It comes into use when you want to match things like unique IDs etc. Read: https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html

You should read about analyzers for elasticsearch. You can create your custom analyzers very easily which can change the data you send them in different ways, like lowercasing everything before they index or search. Luckily, there are pre-configured analyzers for basic operations such as lowercasing. If you change the type of your description and title fields to type: text, your query would work. Read: https://www.elastic.co/guide/en/elasticsearch/reference/current/text.html

Also, i see you have dynamic templates configured for your index. So, if you do not specify the mappings for your index explicitly, all your string fields (like description and title) will be treated as type: keyword. If you build your index like this:

PUT index_name
{
  "mappings": {
    index_type: {
      "properties": {
        "description": {"type": "text"},
        "title": {"type": "text"}, ...
      }
    }
  }
}

your problem should be solved. This is because type: text fields are analyzed by the standard analyzer by default which lowercases the input, among other things. Read: https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-standard-analyzer.html

Sign up to request clarification or add additional context in comments.

2 Comments

It just works. Thank you so much for the help and awesome explanation - I learned a lot. Definitely I'm gonna read about analyzers
Glad to help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.