Elasticsearch query to match two different fields with exact values - elasticsearch

I want to find the record in my elasticsearch index where it should match field "connectorSpecific.hostname.keyword" with value "tyco-fire.com" and field "hasForms" with value true.
Below is my elasticsearch query:
GET index1/_search
{
"query": {
"bool": {
"should": [
{ "match": { "connectorSpecific.hostname.keyword": "tyco-fire.com" }},
{ "match": { "hasForms": true }}
]
}
}
}
This query is returning records which also has field "hasForms" with value false. Not sure why.I am using a boolean should query.Any help is appreciated

If you want both constraints to match, then you should use bool/filter (or bool/must would work as well but since you're doing exact matching, you don't need scoring at all), like this:
GET index1/_search
{
"query": {
"bool": {
"filter": [
{ "match": { "connectorSpecific.hostname.keyword": "tyco-fire.com" }},
{ "match": { "hasForms": true }}
]
}
}
}

Related

Elasticsearch : filter results based on the date range

I'm using Elasticsearch 6.6, trying to extract multiple results/records based on multiple values (email_address) passed to the query (Bool) on a date range. For ex: I want to extract information about few employees based on their email_address (annie#test.com, charles#test.com, heman#test.com) and from the period i.e project_date (2019-01-01).
I did use should expression but unfortunately it's pulling all the records from elasticsearch based on the date range i.e. it's even pulling other employees information from project_date 2019-01-01.
{
"query": {
"bool": {
"should": [
{ "match": { "email_address": "annie#test.com" }},
{ "match": { "email_address": "chalavadi#test.com" }}
],
"filter": [
{ "range": { "project_date": { "gte": "2019-08-01" }}}
]
}
}
}
I also tried must expression but getting no result. Could you please help me on finding employees using their email_address with the date range?
Thanks in advance.
Should(Or) clauses are optional
Quoting from this article.
"In a query, if must and filter queries are present, the should query occurrence then helps to influence the score. However, if bool query is in a filter context or has neither must nor filter queries, then at least one of the should queries must match a document."
So in your query should is only influencing the score and not actually filtering the document. You must wrap should in must, or move it in filter(if scoring not required).
GET employeeindex/_search
{
"query": {
"bool": {
"filter": {
"range": {
"projectdate": {
"gte": "2019-01-01"
}
}
},
"must": [
{
"bool": {
"should": [
{
"term": {
"email.raw": "abc#text.com"
}
},
{
"term": {
"email.raw": "efg#text.com"
}
}
]
}
}
]
}
}
}
You can also replace should clause with terms clause as in #AlwaysSunny's answer.
You can do it with terms and range along with your existing query inside filter in more shorter way. Your existing query doesn't work as expected because of should clause, it makes your filter weaker. Read more here:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
{
"query": {
"bool": {
"filter": [
{
"terms": {
"email_address.keyword": [
"annie#test.com", "chalavedi#test.com"
]
}
},
{
"range": {
"project_date": {
"gte": "2019-08-01"
}
}
}
]
}
}
}

Search document even when some fields are missing in elastic search

I want to search student based on centerId, courseId and batchId. For example i have student data as below.
{
"s1":{
"name":alex,
"centerId":"N001",
"courseId":"ncjava",
"batchId":"nb1"},
"s2":{
"name":John,
"centerId":"N001",
"courseId":"nc02",
"batchId":"ncb2"},
"s3":{
"name":David,
"centerId":"N001",
"courseId":"ncjava",
}
}
Now i want to search student where centerId,courseId and batchId matches and even want students that have matching centerId and courseId but where batchId is missing. I wrote below query
{
"query": {
"bool": {"must": [
{
"match": {
"centerId":"N001"
}},
{ "match": {
"courseId": "ncjava"
}}
],
"should":[
{
"match": {
"batchId": "nb1"
}
}
]
}
}
}
This query returns me all the student that matches with centerId and courseId. But it also returns me students who have different 'batchId'. I only want student when batchId is matched or it does not exists.
You can add query terms which are "bool", in order to make "or" logic like you want. batchId = X OR batchId is missing can be represented with a should expression (and batchId is missing with a must_not and exists), like this:
{
"query": {
"bool": {
"must": [
{
"match": {
"centerId": "N001"
}
},
{
"match": {
"courseId": "ncjava"
}
},
{
"bool": {
"minimum_should_match": 1,
"should": [
{
"match": {
"batchId": "nb1"
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "batchId"
}
}
}
}
]
}
}
]
}
}
}
You can consider must like "and", and should like "or" (though more flexible than boolean or), and must_not as boolean "not". So, the above query means something like centerId == N001 AND courseId == ncjava AND (batchId == nb1 OR NOT exists batchId).
In this particular context, minimum_should_match actually isn't required (the default behavior is already what you want), but since the behavior is different in different contexts, I like to include it explicitly, in case the query is edited in an unexpected way in the future (then the behavior of the should will remain the same despite the changed context). minimum_should_match of 1 means that at least 1 of the should clauses must match.
Here's the docs for each of these components:
bool query
exists query
minimum_should_match

Exact match in elastic search on multiple key values

I am trying to write a query in elasticsearch with an exact match on multiple fields
I have the following query for an exact match for a single field:
GET /index/data/_search
{
"query": {
"term": {
"table":"abc"
}
}
}
Here the key is "table" and the value is "abc". I would like to add another key called "chair" with value "def for the exact match query.
Use a bool+must or bool+filter query, both act as logical and operator:
GET /index/data/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"table":"abc"
},
{
"term": {
"chair":"def"
}
]
}
}
}

Search in every field with a fixed parameter

Perhaps it's a basic question; by the way, I need to search in every indexed field and to have a specific fixed value for another field.
How can I do it?
Currently I have a simple: query( "aValue", array_of_models )
I tried many options without success, for example:
query({
"query": {
"bool": {
"query": "aValue",
"filter": {
"term": {
"published": "true"
}
}
}
}
})
I would prefer to avoid to specify the fields to search in because I use the same search params for different models.
I found a solution, perhaps it's not optimized but works:
{
"query": {
"bool": {
"should": [
{
"match": {
"_all": "aValue"
}
}
],
"filter": {
"term": {
"published": true
}
}
}
}
}
Not sure if I understood correctly your intention.
The _all field is as default enabled. So if you have no special mapping every indexed field value is added as text string to the _all field.
You can use the
Query String Query, https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html
Simple Query String Query, https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html
With a simple query like this, that should work for you.
GET my_index/_search
{
"query": {
"simple_query_string": {
"query": "aValue",
"fields": []
}
}
}
Both query types contains parameters, that should suffice your use case IMHO.

Elasticsearch query not working on fields with capital letters

I have been using/mapping the string field to being index: "not_analyzed" but still not able to get search results for capital letter strings ?? I searched the whole internet inside out , but there is no simple workaround.
Sample data:
{
"job_status":"Finished",
"build_number":"94",
"build_duration":778,
"#timestamp":"1455317284293",
"build_result":"UNSTABLE",
"slave_node":"tiny-cmsbuild03",
"job_name":"DMWM-WMCore-RunTests-Oracle"
},
{
"job_status":"Finished",
"build_number":"96",
"build_duration":859,
"#timestamp":"1455662929042",
"build_result":"UNSTABLE",
"slave_node":"tiny-cmsbuild02",
"job_name":"DMWM-WMCore-RunTests-Oracle"
},
{
"job_status":"Finished",
"build_number":"89",
"build_duration":385,
"#timestamp":"1454453359226",
"build_result":"UNSTABLE",
"slave_node":"tiny-cmsbuild06",
"job_name":"DMWM-WMCore-RunTests-Oracle"
}
kibana3 is making this query:
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"query_string": {
"query": "job_name:D*"
}
}
]
}
},
"filter": {
"bool": {
"must": [
{
"match_all": {}
}
]
}
}
}
}
but get no results.
The reason you don't get any results is because the query_string query has a parameter called lowercase_expanded_terms which is true by default.
What it does is to lowercase the query string you're passing to it, so that job_name:D* becomes job_name:d*, hence why nothing is matching.
However, if you query like this, i.e. by setting lowercase_expanded_terms to false, it will work:
curl -XGET localhost:9200/your_index/_search?lowercase_expanded_terms=false&q=job_name:D*

Resources