Help with writing a search query


(Chen Leikehmacher) #1

Hello all, nooby here. I'm trying to write a search query but I'm having some problems.

I have an index called Categories. It has the following fields: title, tags (which is just a big string with keywords) and total, a number which represents the total number of items I have for this category.

Given search query T, I want to fetch 10 results where title/tags are T, or begin with T, or contain T. I want to sort them based on score, and then based on total. I also want to disable term frequency consideration into the score. That's the gist of it.

    {
      "index": "categories",
      "body": {
        "size": 10,
        "query": {
          "bool": {
            "minimum_should_match": 1,
            "should": [
              {
                "query_string": {
                  "default_field": "_all",
                  "query": "T"
                }
              },
              {
                "query_string": {
                  "default_field": "_all",
                  "query": "T*"
                }
              },
              {
                "query_string": {
                  "default_field": "_all",
                  "query": "*T*"
                }
              }
            ],
            "must": [
              {
                "range": {
                  "total": {
                    "gt": 0
                  }
                }
              }
            ]
          }
        },
        "sort": {
          "_score": {
            "order": "desc"
          },
          "total": {
            "order": "desc"
          }
        }
      }
    }

This query works, however I'm unable to impose the no-term frequency rule. I've tried writing constant_score to encapsulate each of those query_strings or the bool, but I only got exceptions.

Any ideas? Also, just making sure but am I writing my query correctly, or should I write it in a different fashion? Thanks :slight_smile:


(Nik Everett) #2

Please wrap your code snippets in ``` so discuss doesn't eat the formatting.

Using query_string for user generated queries can be a trap. When query_string doesn't understand some syntax it just sends back an error. I ended up working myself into a local minimal where I had a doen regexes that I ran on use queries to "prepare" them for query_string. Usually you are better of just using match and a match_prefix query.

constant_score should get the job done if you just want each of the two arms of the bool query to be worth a particular amount. Wrap each of the should queries in constant_score.


(Chen Leikehmacher) #3

Alright, sorry about that. I tried to format the JSON before but I guess I didn't do it right.
Anyway, I'm getting the following exception when attempting your solution:
[bool] query does not support [constant_score]

I should've clarified this before but I run my queries via PHP code in a Laravel-based environment. I use elasticsearch version 6.0.1 and ruflin/elastica version 6. Not sure if this will help, but yeah... Any ideas?


(Nik Everett) #4

You should be able to stick a constant_score query in the same place as have query_string now. You'd put the query_string inside the filter object in the constant_score one. That should work.

I used reflin's elastica for years but I haven't worked on that project in a few years. So, if it does matter, I won't know. But it shouldn't matter. Like, from the philosophical standpoint.


(Chen Leikehmacher) #5

Great! I forgot to write filter block inside the constant_score query, that was my problem.
Seems to be working as expected now, thanks for the help! :grin:


(system) #6

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.