Custom Scoring if term found in specific field


(dzintarsrerihs) #1

Hello!

At this point in my app I need to solve scoring implementation task. What I
need to achieve is that - if term is found in *Surname *field, it can get
custom boost that is taken from scoreBoostForSurname otherwise (if term
found in Name then scoreBoostForSurname value is not used)
Lets assume I have simple three documents:
{
"thisID": "1",
"name": "Elastic",
"surname": "Search",
"scoreBoosterForSurname": "0"
}
{
"thisID": "2",
"name": "Search",
"surname": "Elastic",
"scoreBoosterForSurname": "10"
}
{
"thisID": "3",
"name": "Search",
"surname": "Elastic",
"scoreBoosterForSurname": "5"
}
And now lets assume I'm querying these documents.
'
{
query: {bool: {must: [{query_string: {
query: "Elastic",
default_operator: "AND",
analyze_wildcard: true,
fields: [
"name",
"surname",
]
}}]}}
}
'
What I prefer is that if ordered by score results are ordered and returned
to me in this order 2,3,1 (values from *thisID *field)

So what I assume I need here is not custom score, but custom field
boosting. Is it really achievable at the moment in Elastic Search? Or is
there something about custom scoring or even Elastics scoring I don't know
yet?

I checked on nested objects, but does help to solve my task as well as
index with child elements as child elements are not included in final
result when querying parent.

The other options I consider is to use custom score with duplicating user
entries (documents) and then removing duplicated results at my application
side.

--


(Igor Motov) #2

I think you can do it by combining dis_max with custom_score query:

{
"query": {
"dis_max": {
"queries": [{
"query_string": {
"query": "Elastic",
"default_operator": "AND",
"analyze_wildcard": true,
"default_field": "name"
}
},{
"custom_score": {
"query": {
"query_string": {
"query": "Elastic",
"default_operator": "AND",
"analyze_wildcard": true,
"default_field": "surname"
}
},
"script" : "_score * doc['scoreBoosterForSurname'].value"
}
}
]
}
}
}

Here is a full example: https://gist.github.com/3990458

On Wednesday, October 31, 2012 11:58:56 AM UTC-4, dzintarsrerihs wrote:

Hello!

At this point in my app I need to solve scoring implementation task. What
I need to achieve is that - if term is found in *Surname *field, it can
get custom boost that is taken from scoreBoostForSurname otherwise (if
term found in Name then scoreBoostForSurname value is not used)
Lets assume I have simple three documents:
{
"thisID": "1",
"name": "Elastic",
"surname": "Search",
"scoreBoosterForSurname": "0"
}
{
"thisID": "2",
"name": "Search",
"surname": "Elastic",
"scoreBoosterForSurname": "10"
}
{
"thisID": "3",
"name": "Search",
"surname": "Elastic",
"scoreBoosterForSurname": "5"
}
And now lets assume I'm querying these documents.
'
{
query: {bool: {must: [{query_string: {
query: "Elastic",
default_operator: "AND",
analyze_wildcard: true,
fields: [
"name",
"surname",
]
}}]}}
}
'
What I prefer is that if ordered by score results are ordered and returned
to me in this order 2,3,1 (values from *thisID *field)

So what I assume I need here is not custom score, but custom field
boosting. Is it really achievable at the moment in Elastic Search? Or is
there something about custom scoring or even Elastics scoring I don't know
yet?

I checked on nested objects, but does help to solve my task as well as
index with child elements as child elements are not included in final
result when querying parent.

The other options I consider is to use custom score with duplicating user
entries (documents) and then removing duplicated results at my application
side.

--


(dzintarsrerihs) #3

Ok, thank you for your answer. I will see how it works and then give a
feedback on this.

Have a great day!
Dzinars

ceturtdiena, 2012. gada 1. novembris 00:50:16 UTC+2, Igor Motov rakstīja:

I think you can do it by combining dis_max with custom_score query:

{
"query": {
"dis_max": {
"queries": [{
"query_string": {
"query": "Elastic",
"default_operator": "AND",
"analyze_wildcard": true,
"default_field": "name"
}
},{
"custom_score": {
"query": {
"query_string": {
"query": "Elastic",
"default_operator": "AND",
"analyze_wildcard": true,
"default_field": "surname"
}
},
"script" : "_score * doc['scoreBoosterForSurname'].value"
}
}
]
}
}
}

Here is a full example: https://gist.github.com/3990458

On Wednesday, October 31, 2012 11:58:56 AM UTC-4, dzintarsrerihs wrote:

Hello!

At this point in my app I need to solve scoring implementation task. What
I need to achieve is that - if term is found in *Surname *field, it can
get custom boost that is taken from scoreBoostForSurname otherwise (if
term found in Name then scoreBoostForSurname value is not used)
Lets assume I have simple three documents:
{
"thisID": "1",
"name": "Elastic",
"surname": "Search",
"scoreBoosterForSurname": "0"
}
{
"thisID": "2",
"name": "Search",
"surname": "Elastic",
"scoreBoosterForSurname": "10"
}
{
"thisID": "3",
"name": "Search",
"surname": "Elastic",
"scoreBoosterForSurname": "5"
}
And now lets assume I'm querying these documents.
'
{
query: {bool: {must: [{query_string: {
query: "Elastic",
default_operator: "AND",
analyze_wildcard: true,
fields: [
"name",
"surname",
]
}}]}}
}
'
What I prefer is that if ordered by score results are ordered and
returned to me in this order 2,3,1 (values from *thisID *field)

So what I assume I need here is not custom score, but custom field
boosting. Is it really achievable at the moment in Elastic Search? Or is
there something about custom scoring or even Elastics scoring I don't know
yet?

I checked on nested objects, but does help to solve my task as well as
index with child elements as child elements are not included in final
result when querying parent.

The other options I consider is to use custom score with duplicating user
entries (documents) and then removing duplicated results at my application
side.

--


(dzintarsrerihs) #4

Yes, this is exactly what I needed. Tested it with more complex queries and
got the result desired.
Once again thank you for your response.

Best Regards,
Dzintars Rerihs

ceturtdiena, 2012. gada 1. novembris 00:50:16 UTC+2, Igor Motov rakstīja:

I think you can do it by combining dis_max with custom_score query:

{
"query": {
"dis_max": {
"queries": [{
"query_string": {
"query": "Elastic",
"default_operator": "AND",
"analyze_wildcard": true,
"default_field": "name"
}
},{
"custom_score": {
"query": {
"query_string": {
"query": "Elastic",
"default_operator": "AND",
"analyze_wildcard": true,
"default_field": "surname"
}
},
"script" : "_score * doc['scoreBoosterForSurname'].value"
}
}
]
}
}
}

Here is a full example: https://gist.github.com/3990458

On Wednesday, October 31, 2012 11:58:56 AM UTC-4, dzintarsrerihs wrote:

Hello!

At this point in my app I need to solve scoring implementation task. What
I need to achieve is that - if term is found in *Surname *field, it can
get custom boost that is taken from scoreBoostForSurname otherwise (if
term found in Name then scoreBoostForSurname value is not used)
Lets assume I have simple three documents:
{
"thisID": "1",
"name": "Elastic",
"surname": "Search",
"scoreBoosterForSurname": "0"
}
{
"thisID": "2",
"name": "Search",
"surname": "Elastic",
"scoreBoosterForSurname": "10"
}
{
"thisID": "3",
"name": "Search",
"surname": "Elastic",
"scoreBoosterForSurname": "5"
}
And now lets assume I'm querying these documents.
'
{
query: {bool: {must: [{query_string: {
query: "Elastic",
default_operator: "AND",
analyze_wildcard: true,
fields: [
"name",
"surname",
]
}}]}}
}
'
What I prefer is that if ordered by score results are ordered and
returned to me in this order 2,3,1 (values from *thisID *field)

So what I assume I need here is not custom score, but custom field
boosting. Is it really achievable at the moment in Elastic Search? Or is
there something about custom scoring or even Elastics scoring I don't know
yet?

I checked on nested objects, but does help to solve my task as well as
index with child elements as child elements are not included in final
result when querying parent.

The other options I consider is to use custom score with duplicating user
entries (documents) and then removing duplicated results at my application
side.

--


(system) #5