Script for search rank (script_score)


(Vitalii) #1

hey guys, i have pb, i have field
rank = {
0: 'js',
1: php
...
}
i need order so i decide use script_score and write this code
script_score{
script = (1 + (doc['rank'].size() > 0 ? doc['rank'].values.find{it =="js"} ? 1 : 0 : 0));
}
but its not help can you help me how find value in arrys in elasticsearch???


(Mark Harwood) #2

Script might not be the best way to achieve what you're after.

Can you afford to reindex your content? If so we can consider some faster solutions


(Vitalii) #3

i know but i need this, because all project already use it, and i need just do order so i need this way


(Vitalii) #4

what do you mean reindex content?


(Mark Harwood) #5

Reorganise your data into a new index with a more appropriate document format/mapping.


(Vitalii) #6

no i can't i have not access to this, but i need change script for order data


(Mark Harwood) #7

If you already have an index you have a source of data from which you can reindex.

Never mind, let's focus on your script for now and what you want to achieve with the existing index.
Looking at the code it seems like you're returning a 1 if you find "js" in the array or or zero if not. Given the field is called "rank" and you're talking about order I presume you want to return a score that is related to the position in the array rather than a simple zero or a one?


(Vitalii) #8

i have around 5 type of rank, i want write script that will add some number for all category for example
if js put 5
it php put 4
if python put 3
and then order by _score


(Mark Harwood) #9

If the query wants to rank certain skills higher than others,regardless of array position, there's no need for scripts:

DELETE test
PUT test
{
   "settings": {
	  "index": {
		 "number_of_shards": 1
	  }    
   },
   "mappings": {
	  "person": {
		 "properties": {
			"skills": {
			   "type": "keyword"
			},
			"name": {
			   "type": "keyword"
			}

		 }
	  }
   }
}
POST test/person
{
	"name":"Mr Webdev",
	"skills":["html", "js"]
}
POST test/person
{
	"name":"Mr PHP Webdev",
	"skills":["php", "js"]
}
POST test/person
{
	"name":"Monty",
	"skills":["python", "flask"]
}

GET test/person/_search
{
   "query": {
	  "bool": {
		 "should": [
			{
			   "constant_score": {
				  "filter": {
					 "term": { "skills": "js" }
				  },
				  "boost": 5
			   }
			},
			{
			   "constant_score": {
				  "filter": { 
					 "term": { "skills": "php" }
				  },
				  "boost": 4
			   }
			},
			{
			   "constant_score": {
				  "filter": {
					 "term": { "skills": "python"}
				  },
				  "boost": 3
			   }
			}
		 ]
	  }
   }
}

(Vitalii) #10

yes tried this way, but you know i have pb, that i need order not only for rank field, i have some other field like experience, and country and other and they should they should be considered too,


(Vitalii) #11

so order should be like this:
first show - rank 'js'
2 -rank php
3 - country - USA
4 - experience 2-3 years
5 - experience1 years
6 - rank - html


(Mark Harwood) #12

Check out function score [1]. That's the way to assemble combinations of multiple matching rules with different boosts and score-blending modes.

[1] https://www.elastic.co/guide/en/elasticsearch/reference/5.1/query-dsl-function-score-query.html


(system) #13

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