scoring - Elasticsearch - using nested object value in Function Score -
i have nested object interest_scores in es looks this:
[{ username: 'somebody', interest_scores: [ { name: 'running', score: 10 } { name: 'food , drinks', score: 21 } ] }, { username: 'somebodyelse', interest_scores: [ { name: 'running', score: 7 } { name: 'food , drinks', score: 29 } ] }] when enter search term running user highest score running returned first.
i know way use function score query not sure how use matching search term in function / script. think query return documents have interest "running" , use interest_scores.{match}.score add or multiply document score.
any appreciated!
as requested, here mapping:
{ "influencers": { "mappings": { "influencer": { "properties": { "email": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "gender": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "geo": { "type": "geo_point" }, "hashtags": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "id": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "interest_scores": { "type": "nested", "properties": { "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "score": { "type": "long" } } }, "interests": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "language": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "location": { "properties": { "city": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "country": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "country_code": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "lat": { "type": "float" }, "lng": { "type": "float" }, "state_code": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "subdivision": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }, "network_data": { "properties": { "facebook": { "properties": { "url": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "username": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }, "instagram": { "properties": { "bio": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "engagement": { "type": "float" }, "id": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "picture": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "reach": { "type": "long" }, "url": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "username": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }, "pinterest": { "properties": { "url": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "username": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }, "twitter": { "properties": { "bio": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "engagement": { "type": "float" }, "id": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "picture": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "reach": { "type": "long" }, "url": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "username": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }, "youtube": { "properties": { "bio": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "engagement": { "type": "float" }, "id": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "picture": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "reach": { "type": "long" }, "url": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "username": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "videos": { "type": "long" }, "views": { "type": "long" }, "views_per_video": { "type": "float" } } } } }, "networks": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "picture": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "total_reach": { "type": "long" }, "username": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } } } i not have function score query yet, testing in dev tools of kibana - have of other filters working correctly though. looking "if search term matches interest_scores.name sort hits interest_scores.score of interest_scores.name
update
the following seems working when test in kibana dev tools:
{ "query": { "nested": { "path": "interest_scores", "score_mode": "sum", "query": { "function_score": { "query": { "match": { "interest_scores.name": "running" } }, "script_score": { "script": "_score + doc['interest_scores.score'].value" } } } } } } i have tested few different search terms , returns highest score first, weird same results when remove script_score function. can tell me if solution, or why works without script_score?
as described here, can sort nested fields:
{ "_source": false, # inner hits - can remove "query": { "nested": { "path": "interest_scores", "filter": { "range": { "interest_scores.score": { "gte": "0" } } }, "inner_hits": {} # inner hits - can remove } }, "sort": { "interest_scores.score": { "order": "desc", "mode": "max", "nested_filter": { "range": { "interest_scores.score": { "gte": "0" } } } } } } *pay attention that, can use inner_hits ability show relevant nested documents. if inner hits documents relevant - please remove marked lines.
**use filter on score field or on other field (e.g: name filter by).
edit 1: if want sorted scores of specific name, try:
{ "_source": false, "query": { "nested": { "path": "interest_scores", "filter": { "term": { "interest_scores.name": "score_name" } }, "inner_hits": {} } }, "sort": { "interest_scores.score": { "order": "desc", "mode": "max", "nested_filter": { "range": { "interest_scores.score": { "gte": "0" } } } } } } put desired score name instead score_name.
Comments
Post a Comment