ElasticSearch : How to combine nested 'AND' Not Equal - search

I want build query for search matching with nested and not equal.
This is my elasticSearch query:
{
"from":0,"size":1000,
"query":{
"nested" : {
"path" : "data",
"query" : {
"match" : {
"data.city" : "california"
}
}
},
"filter":{
"not":{
"filter":{
"term":{
"_id":"01921asda01201"
}
}
}
}
}
}
But I got error, am I write something wrong ? thanks

You can use bool Filter too with must and must_not clause.
{
"from": 0,
"size": 1000,
"filter": {
"bool": {
"must": [
{
"nested": {
"path": "data",
"query": {
"match": {
"data.city": "california"
}
}
}
}
],
"must_not": [
{
"term": {
"_id": "01921asda01201"
}
}
]
}
}
}

You need to use filtered query
GET _search
{
"query": {
"filtered": {
"query": {
"nested": {
"path" : "data",
"query" : {
"match" : {
"data.city" : "california"
}
}
}
},
"filter": {
"bool": {
"must_not": [
{
"term": {
"_id": "01921asda01201"
}
}
]
}
}
}
}
}

You should use a bool query for this, and put your two clauses in the must and must_not sections respectively.
If you don't care about scoring on the data.city field (from your example it's not clear), you might want to use the filter portion instead of the must portion.
{
  "from": 0,
  "size": 1000,
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "data",
            "query": {
              "match": {
                "data.city": "california"
              }
            }
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "_id": "01921asda01201"
          }
        }
      ]
    }
  }
}

Related

elasticsearch must OR must_not

I have this query for my elasticsearch request:
{
"query": {
"bool": {
"filter": {
"bool": {
"should" : [
{
"bool" : {
"must_not": {
"exists": {
"field": "visibility_id"
}
}
}
},
{
"bool" : {
"must": {
"terms": {
"visibility.visibility": ["visible"]
}
}
}
}
]
}
}
}
}
}
The goal is to check if the row visibility_id is in the table. If not it will return true has it reach the "must_not". But if the visibility_id column is present it needs to check that this is set to "visible".
At the moment it works if the visibility_id is null but it does not check the terms. terms can be anything else but visible and it will works.
Can someone help me please, I am new to elasticsearch. (I have tried without the filter, bool, only with the should but it does not work neither.)
Try this query, you're missing minimum_should_match: 1
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must_not": {
"exists": {
"field": "visibility_id"
}
}
}
},
{
"terms": {
"visibility.visibility": [
"visible"
]
}
}
]
}
}
}
If visibility is nested in your mapping, your query needs to be like this instead:
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must_not": {
"exists": {
"field": "visibility_id"
}
}
}
},
{
"nested": {
"path": "visibility",
"query": {
"terms": {
"visibility.visibility": [
"visible"
]
}
}
}
}
]
}
}
}

Update elastic search doc field value for specific fields in all documents

I have documents like this.
{
"a":"test",
"b":"harry"
},
{
"a":""
"b":"jack"
}
I need to update docs with field a==""(empty string) to default value say null in all documents for a given index.
Any help is appreciated. Thanks
Use Update by query with ingest
_update_by_query can also use the Ingest Node feature by specifying a pipeline like this:
define the pipeline
PUT _ingest/pipeline/set-foo
{
"description" : "sets foo",
"processors" : [ {
"set" : {
"field": "a",
"value": null
}
} ]
}
then you can use it like:
POST myindex/_update_by_query?pipeline=set-foo
{
"query": {
"filtered": {
"filter": {
"script": {
"script": "_source._content.length() == 0"
}
}
}
}
}'
OR
POST myindex/_update_by_query?pipeline=set-foo
{
"query": {
"bool" : {
"must" : {
"script" : {
"script" : {
"inline": "doc['a'].empty",
"lang": "painless"
}
}
}
}
}
}
To query a documents with empty string field value, i.e = ''
I did,
"query": {
"bool": {
"must": [
{
"exists": {
"field": "a"
}
}
],
"must_not": [
{
"wildcard": {
"a": "*"
}
}
]
}
}
So overall query to update all docs with field a=="" is,
POST test11/_update_by_query
{
"script": {
"inline": "ctx._source.a=null",
"lang": "painless"
},
"query": {
"bool": {
"must": [
{
"exists": {
"field": "a"
}
}
],
"must_not": [
{
"wildcard": {
"a": "*"
}
}
]
}
}
}

Using Elastic Search to identify failed logins

I have a certain use case that I'm researching involving creating a query that returns events whenever a failed login occurs from two separate accounts on one machine.
I've created the following query, but I'm receiving errors whenever I try to run it.
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter" : {
"term": {
"EventID": "4625"
}
},
"filter" : {
"range" : {
"_timestamp" : {
"gt": "now-15m"
}
}
}
}
},
aggs: {
group_by_host: {
terms: {
field: 'hostname'
},
aggs: {
group_by_user: {
terms: {
field: 'username'
}
}
}
}
}
Any
You need to wrap your filters inside bool. You can refer to docs for more info.
Try this
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"EventID": "4625"
}
},
{
"range": {
"_timestamp": {
"gt": "now-15m"
}
}
}
]
}
}
}
},
"aggs": {
"group_by_host": {
"terms": {
"field": "hostname"
},
"aggs": {
"group_by_user": {
"terms": {
"field": "username"
}
}
}
}
}
}

Convert strings to floats at aggregation time?

Is there any way to convert strings to floats when specifying a histogram aggregation? Because I have documents with fields that are floats but are not parsed by elasticsearch as such, and when I attempt to do a sum using a string field It throws the next error.
ClassCastException[org.elasticsearch.index.fielddata.plain.PagedBytesIndexFieldData
cannot be cast to org.elasticsearch.index.fielddata.IndexNumericFieldData]}]"
I know I could change the mapping, but for the usage case that I have, it would be more handy if I
could specify something like "script : _value.tofloat()" when writing the
aggregation for the field.
This is my code:
{
"query" : {
"bool": {"
must": [
{"match": { "sensorId": "D14UD021808ARZC" }},
{"match": { "variableName": "CAUDAL"}}
]
}
},
"aggs" : {
"caudal_per_month" : {
"date_histogram" : {
"field" : "timestamp",
"interval" : "month"
},
"aggs": {
"totalmonth": {
"sum": {
"field": "value",
"script" : "_value*1.0"
}
}
}
}
}
}
You need this
{
"query": {
"bool": {
"must": [
{
"match": {
"sensorId": "D14UD021808ARZC"
}
},
{
"match": {
"variableName": "CAUDAL"
}
}
]
}
},
"aggs": {
"caudal_per_month": {
"date_histogram": {
"field": "timestamp",
"interval": "month"
},
"aggs": {
"totalmonth": {
"sum": {
"script": "Float.parseFloat(doc['value'].value)"
}
}
}
}
}
}
For a field that's called value: Float.parseFloat(doc['value'].value)

ElasticSearch filtering with geo distance

I'm attempting to filter data with both geo distance and fields like 'has_cctv' or 'has_instant_bookings'.
{
"query" : {
"filtered" : {
"filter" : {
"geo_distance": {
"distance": 10000,
"lat_lng": {
"lat": "51.5073509",
"lon": "-0.1277583"
}
}
}
}
}
}
I've tried many combinations of filtering using terms but can't seem to get past errors. For example:
{
"query" : {
"filtered" : {
"filter" : {
"terms": [
{"term": {"has_cctv": 1}}
],
"geo_distance": {
"distance": 10000,
"lat_lng": {
"lat": "51.5073509",
"lon": "-0.1277583"
}
}
}
}
}
}
This gives me '[terms] filter does not support [has_cctv] within lookup element'. Could this be a problem with my query, or a problem with the way the data is stored?
Here goes the correct query:
POST _search
{
"query": {
"filtered": {
"query": {
"term": {
"has_cctv": {
"value": 1
}
}
},
"filter": {
"geo_distance": {
"distance": 10000,
"lat_lng": {
"lat": "51.5073509",
"lon": "-0.1277583"
}
}
}
}
}
}
Just make sure that lat_lng is stored as geo_point
Thanks
Bharvi
Or you could use an and filter and group the two filters together. And a comparison between bool filter and and/or/not filters: http://www.elasticsearch.org/blog/all-about-elasticsearch-filter-bitsets/
{
"query": {
"filtered": {
"filter": {
"and": {
"filters": [
{
"term": {
"has_cctv": "1"
}
},
{
"geo_distance": {
"distance": 10000,
"lat_lng": {
"lat": "51.5073509",
"lon": "-0.1277583"
}
}
}
]
}
}
}
}
}
Two errors.
As you have more than one filter, you need to add a bool filter and put each filter in a must clause.
Then you don't need a terms filter here but a term filter.

Resources