Combine query string query and nested query


#1

Hello,

I have the following (simplified) document/mapping:

"mappings" : {
  "hotel" : {
    "properties" : {
      "name" : "string",
      "city" : "string",
      "tags" : {
        "type": "nested",
        "properties" : {
          "name" : {
            "type" : "string"
          },
          "rating" : {
            "type" : "integer"
          }
        }
      }
    }
  }
}

I want to provide a search function that supports exact phrase matches and operators like + to force inclusion of certain search terms. So, for example, a search for "new york +spa" should only return results with the term "spa" either in one of the string attributes or in the list of tags.

To make it a bit more interesting, the score of the results should be influenced by the tags' rating.

My naive approach was to use a query like this:

"query" : {
  "bool" : {
    "should" : [ {
      "simple_query_string" : {
        "query" : "new york +spa",
        "fields" : [ "name", "city" ]
      }
    }, {
      "nested" : {
        "query" : {
          "function_score" : {
            "query" : {
              "match" : {
                "name" : {
                  "query" : "new york +spa",
                  "type" : "boolean"
                }
              }
            },
            "functions" : [ {
              "script_score" : {
                "script" : "(doc['rating'].empty ? 1 : doc['rating'].value)"
              }
            } ]
          }
        },
        "path" : "tags"
      }
    } ]
  }
}

But, of course, that way the query string search with operators won't be working as expected, because I have split up the queries.

Any ideas on how to solve this?
Thanks!


(Jason Wee) #2
"function_score": {
    "(query|filter)": {},
    "boost": "boost for the whole query",
    "FUNCTION": {},
    "boost_mode":"(multiply|replace|...)"
}

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html

should not the AND builder filter pass into function score query? it java, it would be something like

BoolFilterBuilder bfb = new BoolFilterBuilder();
FunctionScoreQueryBuilder fsqb = new FunctionScoreQueryBuilder(bfb);

you can use bfb to quickly filter the item u want and then in the fsqb, you can start to give the score for the results?

hth

jason


(system) #3