1

I have a scenario in which external agent generates ranking function dynamically which I want to pass as a query argument instead of statically defining it in search definition file, something like http://localhost:8080/search/?query=honda car&rankfeature.rankingExpression="query(title_match_weight)*matches(title)+query(tags_match_weight)*matches(tags)"&rankfeature.query(title_match_weight)=10&rankfeature.query(tags_match_weight)=20 which I am not able to do now. Do we have solution to achieve this in Vespa?

I have tried foreach in rank expression command to serve this purpose but it doesn't serve flexibility of having any function dynamically.

http://docs.vespa.ai/documentation/ranking.html#using-query-variables explains about macros and I find that macros is taken as rank-feature and rank feature can be passed in the query. So that should mean macro can be passed in the query which can be used in the expression, but it is not possible.

vandit.thakkar
  • 121
  • 1
  • 1
  • 6

1 Answers1

2

It's not possible to send ranking expressions with the query (it wouldn't be efficient as they are (often) compiled with LLVM etc).

Couldn't you use a fixed ranking expression and use query features to weight/or turn on or off different parts of it? You can also configure many different ranking expressions and choose between them at query time using ranking.profile=profileName.

Jon
  • 2,043
  • 11
  • 9
  • I was able to accommodate my ranking function with use of weights and use of `foreach` utility feature availability in Vespa, but when needing only 3-4 fieldMatch features in ranking function (though different everytime), I need to loop through all 100-200 which is not good. So basically, I had achieved my goal, but wanted to know if ranking function can be passed. But this answered my question. – vandit.thakkar Mar 16 '18 at 12:09
  • What do you have 100-200 of that you need to loop over? – Jon Mar 19 '18 at 08:54
  • Number of fields. So I believe when I need to give weights to a limited number of fields and calculate relevance value, it is not good to loop over all fields. Basically, I need to give weight to some field matches but that weight is 0 for 90% of fields, though these fields are not definite. – vandit.thakkar Mar 19 '18 at 10:52
  • I see. But is each query really searching for all those fields? All the features of fields that are not present in the query will be 0. – Jon Mar 20 '18 at 11:38
  • The raw query doesn't know what fields to search for. An external API tells what query term match in what field should give add score in ranking expression. As I am not able to pass ranking expression, I have to write a very generalized, ranking expr `foreach(fields,N,rankingExpression("matches(N),query(N)",true,sum)` where query() is score I will pass as a query feature powered by external API, which is 0 for most fields. So I fear it adds cost of looping over all fields using `foreach` – vandit.thakkar Mar 20 '18 at 13:43
  • 1
    If you want better performance or individual control over the ranking of each field I think you should just write out the full ranking expression: query(field1weight) * (ranking expresson for field1) + query(field2weight) * (ranking expression for field2) + ...). If the weights from the external API just turns fields on or off (weights are just 0 or 1), then you can do away with the query weights and just specify the fields you are searching in the query. I.e send query=field1:term instead of query=term&rankfeature.query(field1weight), and drop the query weights from the ranking expression. – Jon Mar 22 '18 at 09:50