How to compare field with _id in elasticsearch script? - elasticsearch

{
"query":{
"bool":{
"must":{
"match_all":{
}
},
"filter":[
{
"script":{
"source":"doc['id'].value == doc['_id'].value",
"lang":"painless"
}
}
]
}
},
"track_total_hits":true
}
So doc['_id'].value is the line that causing error. How should i compare field value with _id value?
In normal documents "_id" is string and "id" is long, but i broke a few and now in them both are strings, how could I find them?

I think your id field type is keyword, so; you can't call doc['id'].value without .keyword.
try this:
"script": {
"script": {
"source": "doc['id.keyword'].value == doc['_id'].value",
"lang": "painless"
}
}

Related

elasticsearch query dsl show products with higher product quantity at the top

i want to search products based on some filters and a keyword which in my code identified by q. what i trying to do is to show products which product_quantity is not equal to zero at the top.
this is my current query.
"query":{
"bool":{
"filter":[
{
"term":{
"status":{
"value":1
}
}
},
{
"range":{
"published_at":{
"lt":"2022-06-21 14:23:58"
}
}
}
],
"must_not":[
{
"terms":{
"categories.id":[
"2754",
"2377"
]
}
}
],
"should":[
{
"multi_match":{
"fields":[
"title",
"code",
"seo.title",
"categories.title",
"subtitle",
"part_number"
],
"boost":10,
"type":"phrase",
"tie_breaker":0.3,
"query":"cpu"
}
},
{
"multi_match":{
"fields":[
"title",
"seo.title",
"categories.title",
"subtitle"
],
"type":"most_fields",
"fuzziness":"AUTO",
"query":"cpu"
}
}
]
}
},
and this is my script sort query:
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "if(Math.abs(doc['product_quantity'].value) > 0) { 1 } else { 1 }"
},
"order":"desc"
}
},
{
"_score":"desc"
}
but it is not accurate.
my question is what is the best way to search with analyzer and set higher score to products with higher than zero quantity to show at the top.
Your sort clause should be like below, else clause should have value 0 and not 1:
"sort": [
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": "if(Math.abs(doc['qty'].value) > 0) { 1 } else { 0 }"
},
"order":"desc"
}
},
{
"_score":"desc"
}
]

Elasticsearch filter by date range and other field

i have query for grouping data by date and other field, and i want to filter it by range date and email, i have tried filter with only date, and it worked, after applying email query,it also work, but it shows all data.
this is my query looks like:
{
"_source": ["user_email","shipping_address.zipcode","eventtime"],
"query" : {
"bool":{
"filter": {
"range": {
"eventtime":{
"gt": start_date,
"lt": end_date
}
}
},
"should":{
"match_phrase_prefix" : {
"user_email": "christea2045#yahoo.com"
}
}
}
},
"aggs": {
"group_by_date":{
"date_histogram":{
"field" : "eventtime",
"interval" : "1d"
},
"aggs":{
"group_shipzip":{
"terms":{
"field": "shipping_address.zipcode.keyword"
}
}
}
}
}
}
You need to add range and email in must clause
"must": [
{
"range": {
"eventtime":{
"gt": start_date,
"lt": end_date
}
}
},
{
"match_phrase_prefix": {
"user_email": "abc1#yahoo.com"
}
}
]
In your query only filter part is returning result. Since email is in should clause it will return document even if there is no match.
If you are doing a full text match on user_email then it is better to use term query on keyword field
{
"term": {
"user_email.keyword": {
"value": "abc1#yahoo.com"
}
}
}
``

how to check for key exist in elastic-search painless parameters?

How to check for key exists in painless script map parameters.
In below query check a.toString() key exist in params
I've tried everything but didn't get it to work.
Please help me
mapping :
"id": {
"type": "long"
}
query:
{
"query":{
"bool":{
"filter":[
{
"script": {
"script": {
"lang": "painless",
"params": {
"29232":2541,
"minDistance": 0
},
"source": "def a=doc['id'].getValue();double distance=params[a.toString()]; return distance <= 1000 && distance >= params['minDistance']"
}
}
}
]
}
}
}
The params is just a Java Map object. So, the following checks if the key exists in the params and exits early with a false if it does not exist.
GET test/_search
{
"query":{
"bool":{
"filter":[
{
"script": {
"script": {
"lang": "painless",
"params": {
"29232":2541,
"minDistance": 0
},
"source": """
def a=doc['id'].getValue();
if (!params.containsKey(a.toString())) {
return false;
}
double distance=params[a.toString()];
return distance <= 1000 && distance >= params['minDistance']
"""
}
}
}
]
}
}
}

Query based on Fields existing in different Indices in Elasticsearch

I've got the following query
{
"from":0,
"size":50000,
"_source":[
"T121",
"timestamp"
],
"sort":{
"timestamp":{
"order":"asc"
}
},
"query":{
"bool":{
"must":{
"range":{
"timestamp":{
"gte":"2017-01-17 11:44:41.347",
"lte":"2017-02-18 11:44:47.878"
}
}
},
"must":{
"exists":{
"field":"T121"
}
}
}
}
}
http://172.22.23.169:9200/index1,index2,Index3/_search?pretty
With this URL i want to query over a number of indices in Elasticsearch and only return those documents where a specific field exists.
Is it possible to put in a list of fields in the "exists" clause where i define
if "field1" OR "field2" OR "fiedl3" are existing in one of the documents return it, otherwise don't, or do i have to script such a case?
To search across all indices use > http://172.22.23.169:9200/_search?pretty
To search across selected indices add following filter to "bool" filter
"must": {
"terms": {
"_index": [
"index1",
"index2"
]
}
}
For OR'ing multiple "exists", you can use should clause with multiple exists and specify "minimum_should_match" to control searched records.
{
"from":0,
"size":50000,
"_source":[
"T121",
"timestamp"
],
"sort":{
"timestamp":{
"order":"asc"
}
},
"query":{
"bool":{
"must":{
"range":{
"timestamp":{
"gte":"2017-01-17 11:44:41.347",
"lte":"2017-02-18 11:44:47.878"
}
}
},
"should":[
{
"exists":{
"field":"field1"
}
},
{
"exists":{
"field":"field2"
}
},
{
"exists":{
"field":"field3"
}
}
]
}
}
}

Mixing bool and multi match/function score query

I'm currently doing a query that's a mix of multi match and function score. The important bit of the JSON looks like this:
"function_score":{
"query":{
"query_string":{
"query":"some query",
"fields":["id","name","strippedDescription","colourSearch","sizeSearch"]
}
}
}
However, I also want to include results that don't necessarily match the query but have a particular numeric value that's greater than 0. I think a bool query would do this, but I don't know how to use a bool query with a function score query.
I understand that a multi match query is just shorthand for a bool query, and I could expand out the multi match query into its bool counter-part, however, I then don't know how I would do function score within that.
Any ideas? I'm on version 1.1.0 by the way.
Figured it out! I was missing the fact that you can nest multi field queries within bool queries! My final solution looks like this:
{
"query":{
"function_score":{
"query":{
"bool":{
"should": [
{
"range": {
"allBoost": {
"gt": 0
}
}
},{
"multi_match":{
"query":"some search query",
"fields":[
"id",
"name",
"description",
"category"
]
}
}
]
}
},
"functions":[
{
"filter":{
"range": {
"allBoost": {
"gt": 0
}
}
},
"script_score":{
"script":"doc['allBoost'].value"
}
},
{
"filter":{
"range": {
"allBoost": {
"lte": 0
}
}
},
"script_score":{
"script":"_score"
}
}
],
"boost_mode": "replace"
}
}
}

Resources