Query elasticsearch match return inexact document - json

I'm trying to retrieve random documents that contain #maga so I did the following query:
{
"_source": "text",
"query": {
"function_score": {
"query": {
"match": {
"text": "#maga"
}
},
"functions": [
{
"random_score": {}
}
]
}
}
}
The problem is some returned document doesn't contain #maga but just the token maga. Why so? And How can I ivercome this problem?

Related

JMESPATH query expression for matching Value in an Array

I have the following JSON
{
“Record”: [
{
“FirstName": “John”,
“LastName”: “Smith”,
“City”: “Chicago”,
“Possessions”: [
{
“Item”: “TV”
},
{
“Item”: “XBOX-S”
},
{
“Item”: “DVR”
},
{
“Item”: “Setup Box”
}
]
},
{
“FirstName": “Jane”,
“LastName”: “Doe”,
“City”: “Seattle”,
“Possessions”: [
{
“Item”: “DVR”
},
{
“Item”: “PS5”
},
{
“Item”: “FireStick”
}
]
},
{
“FirstName": “Jane”,
“LastName”: “Lee”,
“City”: “Dallas”,
“Possessions”: [
{
“Item”: “TV”
},
{
“Item”: “PS5”
},
{
“Item”: “FireStick”
}
]
}
]
}
How do I get a table of First Name and Last Name by matching a particular possession ("TV") using JMESPATH query?
I need to match the Value in the Array Possessions for each entry in the Record
I have tried using the following query, but it does not work,
Record[?contains(Possessions[].Item, `TV`) == `true`]
anyone knows how this request will work or point me in the right direction, it would be greatly appreciated.

JsonPath query?

I have a JSON file like this:
{
"Resources": {
"myresource1": {
"Properties": {
"keyA": {
"Ref": "resource2"
},
"keyB": "something",
"keyC": {
"another object": {
"Ref": "resource3"
}
}
}
},
"resource2": {
"Properties": {
"keyA": 1,
"keyB": 2
}
},
"resource3": {}
}
}
I'd like a JSON Path query that finds all Resources that have Properties that have a Ref object in them.
So in the JSON above, myresource1 has two properties that satisfy this condition and the Refs are resource2 and resource3.
Is this possible?
I found this query works:
$..Properties.*..Ref
It gives me a list of paths:
[
"$['Resources']['myresource1']['Properties']['keyA']['Ref']",
"$['Resources']['myresource1']['Properties']['keyC']['another object']['Ref']"
]
Is there a better solution?

How to check in elasticsearch if a JSON object has a key using the DSL?

If I have two documents within an index of the following format, I just want to weed out the ones which have an empty JSON instead of my expected key.
A
{
"search": {
"gold": [1,2,3,4]
}
B
{
"search":{}
}
I should just get A json and not B json.
I've tried the exists query to search for "gold" but it just checks for non null values and returns the list.
Note: The following doesn't do what I want.
GET test/_search
{
"query": {
"bool": {
"must": [
{
"exists": { "field": "search.gold" }}
]
}
}
}
This is a simple question but I'm unable to find a way to do it even after searching through their docs.
If someone can help me do this it would be really great.
The simplified mapping of the index is :
"test": {
"mappings": {
"carts": {
"dynamic": "true",
"_all": {
"enabled": false
},
"properties": {
"line_items": {
"properties": {
"line_items_dyn_arr": {
"type": "nested",
"properties": {
"dynamic_key": {
"type": "keyword"
}
}
}
}
}
}
}
}
}
Are you storing complete json in search field?
If this is not the case then please share the mapping of your index and sample data.
Update: Query for nested field:
{
"query": {
"nested": {
"path": "search",
"query": {
"bool": {
"must": [
{
"exists": {
"field": "search.gold"
}
}
]
}
}
}
}
}
For nested type fields we need to specify the path and query to be executed on nested fields since nested fields are indexed as child documents.
Elastic documentation: Nested Query
UPDATE based on the mapping added in question asked:
{
"query": {
"nested": {
"path": "line_items.line_items_dyn_arr",
"query": {
"exists": {
"field": "line_items.line_items_dyn_arr"
}
}
}
}
}
Notice that we used "path": "line_items.line_items_dyn_arr". The reason we require to provide full path is because nested field line_items_dyn_arr is itself under line_items object. Had line_items_dyn_arr be a property of mapping and not the property of object or nested field the previous query would work fine.
Nishant's answer is right but for some reason I could get it working only if the path and field are the whole paths.
The following works for me.
{
"nested": {
"path": "search.gold",
"query": {
"exists": {
"field": "search.gold"
}
}
}
}

Elasticsearch bucket aggregation using concatenated parameter

I'm using Elasticsearch API and the schema of the document as follow
{
name: "",
born_year: "",
born_month: "",
born_day: "",
book_type: "",
price: <some number>,
country: ""
}
Now what I need is to get the document count per each name where born before 1995 (born_year + born_month + born_day < "20051220"). How can i achieve?
I tried this:
{
"query": {
"query_string": {
"query": "country:\"SL\""
}
},
"size": 0,
"aggs": {
"total": {
"terms": {
"field": "name"
}
}
}
}
But I have no idea how can I add filter for the birthday.
As mentioned by #val, you need to add a real date field that you can easily add by concatenating these three fields at creation time.
But how you filter based on date range, there are two ways and both of them will return different result sets
Now the level of filtering is your choice.
You mentioned querying on country field. But you have not mentioned at what level you want to filter on date range. I will give you queries for both the cases.
Mappings- assuming you create a date field.
{
name:"",
born_year:"",
born_month:"",
born_day:"",
book_type:"",
price:<some number>,
country:"",
date : ""
}
Case - 1) Filtering date range for name aggregations only, here documents count will not be effected by the date range filter
{
"query": {
"query_string": {
"query": "country:\"SL\""
}
},
"aggs": {
"total": {
"filter": {
"range": {
"date": {
"gte": "your_date_mx",
"lte": "your_date_min"
}
}
},
"aggs": {
"NAME": {
"terms": {
"field": "name",
"size": 10
}
}
}
}
}
}
Case 2) In this case both your documents count and aggregation will be filtered for date range as we add date range filter at query level.
{
"query": {
"query_string": {
"query": "country:\"SL\""
},
"bool": {
"must": [
{
"range": {
"date": {
"gte": "your_date_mx",
"lte": "your_date_mic"
}
}
}
]
}
},
"aggs": {
"toal": {
"terms": {
"field": "name",
"size": 10
}
}
}
}
So adding a filter to aggregation will effect only aggs count.
Edit -
Approach1) with groovy script try to concatinate the string and parse it to integer and then compare with your input date.
{
"query": {
"bool": {
"must": [
{}
],
"filter": {
"script": {
"script": {
"inline": "(doc['year'].value + doc['month'].value + doc['date'].value).toInteger() > 19910701",
"params": {
"param1": 19911122
}
}
}
}
}
}
}
Make sure when indexing index date(or month) with single digit like 6 as 06
2) Approach 2 - parse the string the exact date(preferred)
{
"query": {
"bool": {
"must": [
{}
],
"filter": {
"script": {
"script": {
"inline": "Date.parse('dd-MM-yyyy',doc['date'].value +'-'+ doc['month'].value +'-'+ doc['year'].value).format('dd-MM-yyyy') > param1",
"params": {
"param1": "04-05-1991"
}
}
}
}
}
}
}
Second approach is much better approach as you don't have to worry about the maintaing the string for each field(date, month, day) to later parse to proper int for comparing.

Elasticsearch the terms filter raise "filter does not support [mediatest]"

my query is like this:
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"online": 1
}
},
{
"terms": {
"mediaType": "flash"
}
}
]
}
}
}
}
}
it raise a QueryParsingException [[comos_v2] [terms] filter does not support [mediaType]],of which the field "mediaType" exactly does not exist in mapping.
my question is why term filter does not raise the Exception?
The above is not a valid Query DSL. In the above Terms filter the values to "mediaType" field should be an array
It should be the following :
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"online": 1
}
},
{
"terms": {
"mediaType": ["flash"]
}
}
]
}
}
}
}
}
Its 2021 I'm using .keyword for an exact text match but you can just as easily omit:
{"query":
{"bool":
{"must":
[
{"term":
{"variable1.keyword":var1Here}
},
{"term":
{"variable2.keyword":var2Here}
}
]
}
}
}
Its simply a matter of "term" vs "terms". Very easy to miss the plural / single aspect of it.
I had a very similar error with this query, in which I was trying to delete a specific zone:
'{"query":{"terms":{"zoneid":25070}}}'
I was getting an error when I ran the above query.
As soon as changed "terms" to "term" the query executed with no issues, like this:
'{"query":{"term":{"zoneid":25070}}}'