Elasticsearch parent-child conditional fetching children - elasticsearch

I have 2 type documents mapped using parent-child relations, mappings as follow:
{
"venue": {
"properties": {
"id": {
"type": "long",
"index": "not_analyzed"
},
"address": {
"type": "string",
"index": "analyzed"
},
"capacity": {
"type": "integer",
"index": "not_analyzed"
},
"rate_standard": {
"type": "nested",
"properties": {
"rate": {
"type": "double",
"precision_step": 1,
"index": "not_analyzed"
},
"minimum": {
"type": "integer",
"index": "not_analyzed"
}
}
}
}
},
"calendar": {
"_parent": {
"type": "venue"
},
"properties": {
"day": {
"type": "date",
"format": "yyyy-MM-dd",
"precision_step": 1,
"index": "not_analyzed"
},
"is_available": {
"type": "boolean",
"index": "not_analyzed"
},
"rate": {
"type": "double",
"precision_step": 1,
"index": "not_analyzed"
},
"minimum": {
"type": "integer",
"index": "not_analyzed"
}
}
}
}
I would like to run queries against them as follows:
capacity gte 2
address has all the words of mampang jakarta indonesia
must not have calendar entry (child) with attribute is_available = false, between 2014-01-01 to 2014-12-01
Had tried to build the query but its seems messed up at nesting bool query
{
"query": {
"bool": {
"must": [
{
"range": {
"capacity": {
"gte": 2
}
}
},
{
"match": {
"address": {
"query": "mampang jakarta indonesia",
"operator": "and"
}
}
}
],
"must_not": {
"has_child": {
"type": "calendar",
"query": {
"bool": {
"must": [
{
"term": {
"available": false
}
},
{
"range": {
"day": {
"gte": "2014-01-01",
"lte": "2014-12-01"
}
}
}
],
"must_not": {},
"should": {}
}
}
}
},
"should": {}
}
}
}

This one seems to works
{
"query": {
"bool": {
"must": [
{ "range" : {"capacity": { "gte": 2 }} },
{ "match": {"address": { "query" : "mampang jakarta indonesia", "operator" : "and" }} }
],
"must_not": [
{
"has_child": {
"type": "calendar",
"query": {
"bool": {
"must":[
{"term": {"available" : false }},
{"range": {"day": {"gte": "2014-01-01", "lte": "2014-12-01" }}}
]
}
}
}
}
]
}
}
}
Tho still unsure if this is the appropriate query to achive that

Related

using match_phrase twice on ES query filter? No filter registered for [match_phrase]

I have been trying to fetch a document using multiple filters.
Im currently using ES 1.7 Is it possible to use match_phrase twice on a filter?
example: people document
q=aaron&address=scarborough - searching a person by name and address, works fine.
{
"query": {
"match_phrase": {
"name": "aaron"
}
},
"filter": {
"bool": {
"must": {
"nested": {
"path": "addresses",
"query": {
"match_phrase": {
"address": "scarborough"
}
}
}
}
}
},
q=aaron&phone=813-689-6889 - searching a person by name and phone number works fine as well.
{
"query": {
"match_phrase": {
"name": "aaron"
}
},
"filter": {
"bool": {
"must": {
"query": {
"match_phrase": {
"phone": "813-689-6889"
}
}
}
}
}
However, When I try to use both filters, address and phone I get a No filter registered for [match_phrase] error
for example: q=aaron&address=scarborough&phone=813-689-6889
{
"query": {
"match_phrase": {
"name": "aaron"
}
},
"filter": {
"bool": {
"must": {
"nested": {
"path": "addresses",
"query": {
"match_phrase": {
"address": "scarborough"
}
}
},
"query": {
"match_phrase": {
"phone": "813-689-6889"
}
}
}
}
}
the error, when using address and phone filters together:
nested: QueryParsingException[[pl_people] No filter registered for [match_phrase]]; }]","status":400}):
index mapping (person) as requested:
{
"pl_people": {
"mappings": {
"person": {
"properties": {
"ac_name": {
"type": "string",
"analyzer": "autocomplete"
},
"date_of_birth": {
"type": "date",
"format": "dateOptionalTime"
},
"email": {
"type": "string"
},
"first_name": {
"type": "string",
"fields": {
"na_first_name": {
"type": "string",
"index": "not_analyzed"
}
}
},
"last_name": {
"type": "string",
"fields": {
"na_last_name": {
"type": "string",
"index": "not_analyzed"
}
}
},
"middle_name": {
"type": "string",
"fields": {
"na_middle_name": {
"type": "string",
"index": "not_analyzed"
}
}
},
"name": {
"type": "string",
"fields": {
"na_name": {
"type": "string",
"index": "not_analyzed"
},
"ngram_name": {
"type": "string",
"analyzer": "my_start"
},
"ns_name": {
"type": "string",
"analyzer": "no_stopwords"
}
}
},
"phone": {
"type": "string"
},
"time": {
"type": "date",
"format": "dateOptionalTime"
},
"updated_at": {
"type": "date",
"format": "dateOptionalTime"
}
}
}
}
}
}
Maybe you can use term-filter, instead of match_phrase as a filter.
See here.

ElasticSearch query doesn't return documents that have an "empty" nested property

I'm running into a weird problem. I have a document mapping for which one of the properties is a nested object.
{
"userLog": {
"properties": {
"userInfo": {
"userId": {
"type": "text"
},
"firstName": {
"type": "text"
},
"lastName": {
"type": "text"
},
"email": {
"type": "text"
}
},
"violations": {
"type": "integer"
},
"malfunctions": {
"type": "integer"
},
"extensionsUsed": {
"type": "integer"
},
"date": {
"type": "date",
"format": "yyyy-MM-dd||yyyy/MM/dd||yyyyMMdd||epoch_millis"
},
"events": {
"type": "nested",
"properties": {
"editorId": {
"type": "text"
},
"editorRole": {
"type": "text"
},
"editedTimestamp": {
"type": "date",
"format": "epoch_millis"
},
"createdTimestamp": {
"type": "date",
"format": "epoch_millis"
},
"userId": {
"type": "text"
},
"timestamp": {
"type": "date",
"format": "epoch_millis"
},
"eventType": {
"type": "text"
}
}
}
}
}
}
Some userLogs have events and some don't. My queries only return userLogs that have events, however, and I'm not sure why. There are definitely userLogs that exist without events in the index. I can see them in Kibana. They just aren't returned in the search. Here's what I'm running for a query:
GET index_name/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"date": {
"gte": "20170913",
"format": "yyyyMMdd"
}
}
}
],
"should": [
{
"match_phrase": {
"userInfo.userId": "Xvo9qblajOVaM3bQQMaV4GKk7S42"
}
}
],
"minimum_number_should_match": 1
}
}
}
based on this discussion
I modified my query to be the following:
GET one20_eld_portal/_search
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "events",
"query": {
"bool": {
"filter": {
"exists": {
"field": "events.userId"
}
}
}
}
}
}
],
"should": [
{
"match_phrase": {
"userInfo.uid": "Xvo9qblajOVaM3bQQMaV4GKk7S42"
}
}
],
"minimum_should_match": 1
}
}
}
but this doesn't return any results. Any help is greatly appreciated!
Turns out the reason the "empty" logs weren't being returned is because the userId wasn't being set properly for empty logs.

ElasticSearch sorting nested with condition

With ElasticSearch I want to insert a condition to sort nested fields.
I have this mapping
{
"dario": {
"mappings": {
"agents": {
"properties": {
"applications": {
"type": "nested",
"properties": {
"companies": {
"type": "nested",
"properties": {
"active": {
"type": "integer"
},
"application_date": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
"application_date_month": {
"type": "date",
"format": "yyyy-MM"
},
"application_id": {
"type": "long"
},
"assigned_date": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
"buy_date": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
"date": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
"date_month": {
"type": "date",
"format": "yyyy-MM"
},
"favorite": {
"type": "integer"
},
"id": {
"type": "long"
},
"notes": {
"type": "nested",
"properties": {
"date": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
"id": {
"type": "integer"
},
"note": {
"type": "string",
"analyzer": "standard"
}
}
},
"score": {
"type": "long"
},
"state": {
"type": "long"
},
"view": {
"type": "integer"
},
"visible": {
"type": "integer"
},
"visible_date": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
}
}
},
"count": {
"type": "integer"
},
"sectors": {
"type": "long"
}
}
}
}
}
}
}
}
I want to sort by the field applications.companies.buy_date, but, if this is null, then i want to consider applications.companies.date
I tried with groovy script:
{
"size": 10,
"from": 0,
"sort": [
{
"_script": {
"script": "doc['applications.companies.buy_date'] != null ? doc['applications.companies.buy_date'].date.getMillisOfDay() : doc['applications.companies.date'].date.getMillisOfDay()",
"type": "number",
"nested_filter": {
"match": {
"applications.companies.id": 711
}
},
"order": "desc"
}
}
],
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"nested": {
"path": "applications.companies",
"query": {
"bool": {
"must": [
{
"match": {
"applications.companies.active": 1
}
},
{
"match": {
"applications.companies.id": 711
}
},
{
"bool": {
"should": [
{
"exists": {
"field": "applications.companies.buy_date"
}
},
{
"match": {
"applications.companies.favorite": 1
}
}
]
}
}
]
}
}
}
}
]
}
}
]
}
}
]
}
}
}
but nothing change. Any ideas?
UPDATE
I resolved issue with this solution
{
"size": 10,
"from": 0,
"_source": [
"id"
],
"sort": [
{
"_script": {
"script": {
"script": " if (doc['applications.companies.id'].value == 711) { return (doc['applications.companies.buy_date'].value > 0) ? doc['applications.companies.buy_date'].value : doc['applications.companies.date'].value; } else { return null; } ",
"lang": "groovy"
},
"type": "number",
"order": "desc",
"nested_path": "applications.companies",
"nested_filter": {
"match": {
"applications.companies.id": 711
}
}
}
}
],
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"nested": {
"path": "applications.companies",
"query": {
"bool": {
"must": [
{
"match": {
"applications.companies.active": 1
}
},
{
"match": {
"applications.companies.id": 711
}
},
{
"bool": {
"should": [
{
"exists": {
"field": "applications.companies.buy_date"
}
},
{
"match": {
"applications.companies.favorite": 1
}
}
]
}
}
]
}
}
}
}
]
}
}
]
}
}
]
}
}
}

ElastiSeach Constant score filter query

I have ES 1.7 mapping like below,
PUT tagcloud_v3
{
"mappings": {
"_default_": {
"_all": {
"enabled": false
},
"_source": {
"compressed": true
},
"properties": {
"term": {
"fields": {
"raw": {
"index": "not_analyzed",
"analyzer": "lowercase_analyzer",
"type": "string"
}
},
"analyzer": "concat_all_alpha",
"type": "string"
},
"relation": {
"properties": {
"term": {
"type": "string",
"analyzer": "concat_all_alpha",
"fields": {
"raw": {
"index": "not_analyzed",
"analyzer": "lowercase_analyzer",
"type": "string"
}
}
},
"weight": {
"type": "double"
},
"updatedDate": {
"index": "no",
"type": "date"
},
"isActive": {
"type": "boolean"
},
"rel": {
"type": "string"
},
"source": {
"index": "no",
"type": "string"
},
"lastModifiedBy":{
"index":"no",
"type":"string"
}
}
},
"updatedDate": {
"index": "no",
"type": "date"
},
"isActive": {
"type": "boolean"
},
"lastModifiedBy": {
"index": "no",
"type": "string"
},
"source": {
"index": "no",
"type": "string"
}
}
}
},
"settings": {
"index": {
"analysis": {
"analyzer": {
"concat_all_alpha": {
"char_filter": [
"only_alphanum"
],
"filter": [
"lowercase"
],
"tokenizer": "keyword"
},
"uppercase_analyzer": {
"filter": "uppercase",
"tokenizer": "keyword"
},
"lowercase_analyzer": {
"filter": "lowercase",
"tokenizer": "keyword"
}
},
"char_filter": {
"only_alphanum": {
"pattern": "[^A-Z^a-z^0-9]|\\^",
"replacement": "",
"type": "pattern_replace"
}
}
},
"max_result_window": "1000000"
}
}
}
We are searching same term again and again. We want to use ES filter caching for this. I have used constant_score search query for this,(Note: for any search we will have only one result/ or None.)
GET tagcloud_v3/ITTEST/_search
{
"size": 1,
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"constant_score": {
"filter": {
"term": {
"term": "java"
}
}
}
},
{
"constant_score": {
"filter": {
"term": {
"isActive": true
}
}
}
}
]
}
},
{
"bool": {
"must": {
"nested": {
"query": {
"bool": {
"must": [
{
"constant_score": {
"filter": {
"term": {
"relation.term": "java"
}
}
}
},
{
"constant_score": {
"filter": {
"term": {
"relation.isActive": true
}
}
}
},
{
"constant_score": {
"filter": {
"term": {
"relation.rel": "S"
}
}
}
}
]
}
},
"path": "relation"
}
}
}
}
]
}
}
}
Is my search query is right?. Our ES mapping is fixed.

Elasticsearch using nested object mappings in has_parent filter

Is it possible to use nested object mappings in a has_parent query or filter? Whenever I try I always get:
[customers_and_messages] [nested] nested object under path [accounts]
is not of nested type]
Mapping
{
"customer": {
"properties": {
"name": {
"analyzer": "name_edge_ngram_analyzer",
"type": "string"
},
"phone_number": {
"analyzer": "phone_number_edge_ngram_analyzer",
"type": "string"
},
"location_id": {
"index": "not_analyzed",
"type": "string"
},
"accounts": {
"type": "nested",
"properties": {
"id": {
"index": "not_analyzed",
"type": "string"
},
"tags": {
"type": "string"
},
"notes": {
"type": "string"
}
}
}
}
}
}
Query
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"has_parent": {
"type": "customer",
"filter": {
"nested": {
"path": "accounts",
"filter": {
"term": {
"accounts.id": "8392f356-d6ec-11e4-8737-b74c1bacfb15"
}
}
}
}
}
}
],
"should": [
{
"term": {
"kind": "task"
}
},
{
"term": {
"kind": "alert"
}
}
]
}
}
}
}
}

Resources