ElasticSearch Function Score Query not defaulting to 1 if missing field - elasticsearch

I am trying to create a function score in ElasticSearch that (after other filters) gives a higher score to those customers who bought a product recently. For this I have a field "lastPurchaseOn".
The query also needs to return customers who did not buy any product, so I cannot filter on the lastPurchaseOn field being present.
"functions": [
{
"exp": {
"lastPurchaseOn": {
"scale": "3d"
}
}
},
...
]
The problem is that when the field "lastPurchaseOn" is missing, the function returns score 1, when I would really want it to return 0.
Is there a way to make the function return 0 for missing values?
Thanks

The official documentation states it pretty clearly:
If the numeric field is missing in the document, the function will return 1.
The main reason is that there's no way for the exponential function that is being used to return 0. You can try to use a linearfunction instead of exp.

Related

cant use any filter parameters on graphql in strapi

I have been unable to use any of the filter parameters on graphl query in strapi using the url (http://localhost:1337/graphql). I am using strapi 3.6.8 . I have a collection (Animals) that has an array of Habitat. When I try to limit the number of Habitat returned for each record to 3, it doesn't work with the query below.
query{
Animals {
id
Habitat(limit: 3) {
Feature {
Weight
Height
Lifespan
}
}
}
}
I get the error message: "Unknown argument "limit" on field "Animal.Habitat"."
the limit, where or any other filter does not work. They work however when I use them on the Animals itself. Kindly help
If you are on graphql playground, try pressing CTRL + SPACE and you will see the available parameters that you can use inside your query. In your case, I assume you want to use the pagination feature provided by Strapi. The following query should work.
query {
Animals {
id
Habitat(pagination: { limit: 3 }) {
Feature {
Weight
Height
Lifespan
}
}
}
}

Need a customized index in the elasticsearch

My query is, if i search for a keyword "apparel" my current result is
{
"_index":"myindex",
"_type":"pages",
"_id":"www.abc.com",
"_score":1.726047,
"_source":{
"organization_website":"www.abc.com",
"organization_values":[
{
"unpsc":15,
"industry":"apparel",
"codevalue":0.15
},
{
"unpsc":20,
"industry":"textile",
"codevalue":0.2
}
]
}
}
I can override the _score in Elasticsearch using function score, but i need to add the add the score (which i have created) as the default score in the index. For instance if i search for the keyword "apparel", the default score will 1 , but i want to override the score of the apparel (which i have created) i.e unpsc value to the score.
Is this possible to create a index in the elasticsearch to refer an another node as a default score or i have go with the function score/ boost.....?
I don't think it's possible to assign a default score based on some value.
You'll have to use function score as suggested by yourself.

Exclude setting on integer field in term query

My documents contain an integer array field, storing the id of tags describing them. Given a specific tag id, I want to extract a list of top tags that occur most frequently together with the provided one.
I can solve this problem associating a term aggregation over the tag id field to a term filter over the same field, but the list I get back obviously always starts with the album id I provide: all documents matching my filter have that tag, and it is thus the first in the list.
I though of using the exclude field to avoid creating the problematic bucket, but as I'm dealing with an integer field, that seems not to be possible: this query
{
"size": 0,
"query": {
"term": {
"tag_ids": "00001"
}
},
"aggs": {
"tags": {
"terms": {
"size": 3,
"field": "tag_ids",
"exclude": "00001"
}
}
}
}
returns an error saying that Aggregation [tags] cannot support the include/exclude settings as it can only be applied to string values.
Is it possible to avoid getting back this bucket?
This is, as of Elasticsearch 1.4, a shortcoming of ES itself.
After the community proposed this change, the functionality has been added and will be included in Elasticsearch 1.5.0.
It's supposed to be fixed since version 1.5.0.
Look at this: https://github.com/elasticsearch/elasticsearch/pull/7727
While it is enroute to being fixed: My workaround is to have the aggregation use a script instead of direct access to the field, and let that script use the value as string.
Works well and without measurable performance loss.

Can elasticsearch return multiple value fields in a single facet?

I am looking for a way to create a facet such that I can essentially return two values for one key.
For instance, I am attempting to retrieve both an amount and schedule properties of an object. I attempted to use a computed value script, but the calculations that have to be done using the two objects are date based, and require an external library to perform them.
Basically, something along the lines of:
"theFacet": {
"terms_stats": {
"key_field": "someKeyProbablyADate",
"value_field": "amount",
"value_field": "simpleSchedule"
}
}
Workarounds are also appreciated. Perhaps some way to return a new dynamic object with both fields?
Sounds like you want to pre-process your data before you index it into a single field, then facet on that.
Something among the line of a single string containing key#amount#schedule
Then when you get the faceting results back you can split it up again and run whatever logic you want.
Try combining different fields with a script element. For example:
"facets": {
"facet-name": {
"terms": {
"field": "some-field",
"script": "_source['another-field'] + '/' + term
}
}
}

How to I make a field sortable in ElasticSearch?

I have tried, for example:
{
"sort": [
{
"retail_price": {
"reverse": true
}
}
]
}
... to no avail. Do I need to map the field a special way in order to enable sorting on it?
The field should satisfy two conditions: 1) it has to be indexed and 2) it shouldn't have more than one value per document or more than one token per field. If retail_price is indexed in your case and it still doesn't work for you, could you post a script that demonstrates the problem?

Resources