I'm using ES 7.14/Kibana 7.10, I have to search for adjacent words (any order), hence I'm using this query:
{
"query":{
"bool":{
"must":[
{
"query_string":{
"query":"*antonio* *banderas*",
"fields":[
"text"
],
"default_operator":"and",
}
}]
}
}
}
This works ok for a text plain field. Now, I have a nested field metadata, let's say the mapping is
{
"mappings:": {
"properties": {
"text": {
"type": "text"
},
"metadata": {
"type": "nested",
"properties": {
"text": {
"type": "text"
}
}
}
}
}
}
and I would like to search that nested field in the same way (adjacent words search), so assumed that it's is possibile to write a nested query for query_string in this way
{
"query": {
"query_string": {
"query": "metadata.text:*antonio* *banderas*"
}
}
}
How to adapt this approach to the previous one with default_operator=and etc.? If I do
{
"query": {
"query_string": {
"query": "metadata.text:*antonio* *banderas*",
"default_operator": "and"
}
}
}
I don't get any result (but any error too).
A similar question, but related to matching adjacent words for multiple nested fields is here.
Adjacent word with any order should not be search with query_string but wildcard or match or term or span_term
There is also a mapping type wildcard optimised for this usage, depends on what type of queries you will need.
So for you first example :
{
"query": {
"bool": {
"must": [
{
"wildcard": {
"text": "*antonio*"
}
},
{
"wildcard": {
"text": "*banderas*"
}
}
]
}
}
}
OR
{
"query": {
"bool": {
"must": [
{
"wildcard": {
"text": "*antonio*banderas*"
}
}
]
}
}
}
and for nested queries :
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "metadata",
"query": {
"bool": {
"must": [
{
"wildcard": {
"metadata.text": "*antonio*"
}
},
{
"wildcard": {
"metadata.text": "*banderas*"
}
}
]
}
}
}
}
]
}
}
}
Related
I'm trying to get exact search with slug in nested element in ElasticSearch but it seems like that it doesn't work.
So when i'm trying a simple nested match with "my-slug" i get result with "my" and "slug", Normal...
GET my-index/_search
{
"query": {
"nested": {
"path": "productTranslation",
"query": {
"bool": {
"must": [
{
"match": {
"productTranslation.slug": "my-slug"
}
}
]
}
}
}
}
}
But i have no result when i'm trying with term or filter search.
GET my-index/_search
{
"query": {
"nested": {
"path": "productTranslation",
"query": {
"bool": {
"filter": [
{
"term": {
"productTranslation.slug": "my-slug"
}
}
]
}
}
}
}
}
Any idea where the error lies??
Thank's for help.
Term query doesn't perform any analysis on the term. So, in term query you need to have an exact match.
If you have not explicitly defined any mapping then you need to add .keyword to the productTranslation.slug field. This uses the keyword analyzer instead of the standard analyzer (notice the ".keyword" after productTranslation.slug field).
{
"query": {
"nested": {
"path": "productTranslation",
"query": {
"bool": {
"filter": [
{
"term": {
"productTranslation.slug.keyword": "my-slug" // note this
}
}
]
}
}
}
}
}
OR you can change the data type of the productTranslation.slug field to keyword type
{
"mappings": {
"properties": {
"productTranslation": {
"properties": {
"slug": {
"type": "keyword"
}
}
}
}
}
}
can percolator queries reference other stored query docs in a percolator index? For example, given I have the following Boolean query, with _id=1, already indexed in the percolator:
{
"query": {
"bool": {
"must": [
{ "term": { "tag": "wow" } }
]
}
}
}
Could I have another query, with _id=2, indexed (note that I'm making up the _percolator_ref_id terms query key):
{
"query": {
"bool": {
"should": [
{ "term": { "tag": "elasticsearch" } },
{ "terms" : { "_percolator_ref_id": [1] } }
]
}
}
}
If I percolated the following document:
{ "tag": "wow" }
I would expect both _id=1 and _id=2 queries to match. Does some functionality like _percolator_ref_id exist?
Thanks!
Edit: To clarify, I do not know beforehand how many query references appear in a given query (e.g., the _id=2 query could reference 10 other queries potentially).
You can do something like below
2 queries are registered in below index
PUT myindex
{
"mappings": {
"properties": {
"query1": {
"type": "percolator"
},
"query": {
"type": "percolator"
},
"field": {
"type": "text"
}
}
}
}
You can use bool and must/should to combine different queries
GET /myindex/_search
{
"query": {
"bool": {
"must": [
{
"percolate": {
"field": "query",
"document": {
"field": "fox jumps over the lazy dog"
}
}
},
{
"percolate": {
"field": "query1",
"document": {
"field": "fox jumps over the lazy dog"
}
}
}
]
}
}
}
I have to combine two filters to match requirements:
- a specific list of values in r.status field
- one of the multiple text fields contains the value.
Result query (with using Nest, but it doesn't matter) looks like:
{
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"term": {
"isActive": {
"value": true
}
}
},
{
"nested": {
"query": {
"bool": {
"must": [
{
"terms": {
"r.status": [
"VALUE_1",
"VALUE_2",
"VALUE_3"
]
}
},
{
"bool": {
"should": [
{
"match": {
"r.g.firstName": {
"type": "phrase",
"query": "SUBSTRING_VALUE"
}
}
},
{
"match": {
"r.g.lastName": {
"type": "phrase",
"query": "SUBSTRING_VALUE"
}
}
}
]
}
}
]
}
},
"path": "r"
}
}
]
}
}
]
}
}
}
Also tried with multi_match query:
{
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"term": {
"isActive": {
"value": true
}
}
},
{
"nested": {
"query": {
"bool": {
"must": [
{
"terms": {
"r.status": [
"VALUE_1",
"VALUE_2",
"VALUE_3"
]
}
},
{
"multi_match": {
"query": "SUBSTRING_VALUE",
"fields": [
"r.g.firstName",
"r.g.lastName"
]
}
}
]
}
},
"path": "r"
}
}
]
}
}
]
}
}
}
FirstName and LastName are configured in index mappings as text:
"firstName": {
"type": "text"
},
"lastName": {
"type": "text"
}
Elastic gives a lot of full-text search options: multi_match, phrase, wildcards etc. But all of them fail in my case looking a sub-string in my text fields. (terms query and isActive one work well, I just tried to run only them).
What options do I have also or maybe where I made a mistake?
UPD: Combined wildcards worked for me, but such query looks ugly. Looking for a more elegant solution.
The elasticsearch way is to use ngram tokenizer.
The ngram analyzer will split your terms with a sliding window. For example, the input "Hello World" will generate the following terms:
Hel
Hell
Hello
ell
ello
...
Wor
World
orl
...
You can configure the minimum and maximum size of the sliding window (in the example the minimum size is 3). Once the sub terms are generated you can use a match query an the subfield.
Another point, it is weird to use must within a filter. If you are interested in the score, you should always use must otherwise use filter. Read this article for a good understanding.
I'm trying to have multiple wildcard query match in my elasticsearch query in Kibana. I can't quite figure it out.
Basically I want any document with an attribute type="erreur"
and I want to exclude all documents that match the strings "An established*" or "java.lang.*" on the field descr_courte
{
"query": {
"bool": {
"must": {
"term": {
"type": "erreur"
}
},
"must_not": {
"wildcard": {
"descr_courte": ["An established*", "java.lang.*"]
}
}
}
}
}
if I put a single wildcard query it works fine
{
"query": {
"bool": {
"must": {
"term": {
"type": "erreur"
}
},
"must_not": {
"wildcard": {
"descr_courte":
"An established*"
}
}
}
}
}
the error I get:
Error: Request to Elasticsearch failed: {"error":{"root_cause":[{"type":"illegal_state_exception","reason":"Can't get text on a START_ARRAY at 1:454"}],"type":"search_phase_execution_exception","reason":"all shards
Any idea?
Try putting them is separate clauses.
{
"query": {
"bool": {
"must": {
"term": {
"type": "erreur"
},
"must_not": [
{
"wildcard": {
"descr_courte": "An established*"
}
},
{
"wildcard": {
"descr_courte": "java.lang.*"
}
}
]
}
}
}
}
My guess is that you can't make an array for wildcard query like ["An established*", "java.lang.*"], so you need to:
{
"query": {
"{
"must": {
"term": {
"type": "erreur"
}
},
"must_not": {
"regexp": {
"descr_courte": "(An established|java\.lang\.).*"
}
}
}
}
}
More info about regexp query in https://www.elastic.co/guide/en/elasticsearch/reference/5.1/query-dsl-regexp-query.html
Another option is to combine your query terms with the logical operators NOT, AND and OR in the query string
{
"query": {
"query_string" : {
"query" : "type:erreur AND NOT(descr_courte:An established* OR descr_courte:java.lang.*)"
}
}
}
See more info at https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#_wildcards
I am trying to implement NOT condition in elasticsearch query.
Can I Implement filter inside bool or I need to write separate
filter as below. Any optimum solution is there?
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "fashion"
}
},
{
"term": {
"post_status": "publish"
}
}
]
}
},
"filter": {
"not": {
"filter": {
"term": {
"post_type": "page"
}
}
}
}
}
You can use a must_not clause:
{
"query": {
"bool": {
"must": [
{
"match": {
"_all": "fashion"
}
},
{
"term": {
"post_status": "publish"
}
}
],
"must_not": {
"term": {
"post_type": "page"
}
}
}
}
}
Also, I'd recommend using a match filter instead of query_string, as query_string requires the much more strict Lucene syntax (and is therefor more error prone), whereas match works more like a search box: it will automatically transform a human readable query to a Lucene query.