I've found 2 approaches for Like-Search in Elasticsearch. Which one of those whould I choose? They seem to have the same behaviour. Or is there even a better one?
query_string:
"query": {
"bool": {
"filter": [
{
"query_string": {
"query": "*quick*",
"fields": [
"text"
]
}
}
]
}
}
wildcard:
"query": {
"bool": {
"must": [
{
"wildcard": {
"text": "*quick*"
}
}
]
}
}
SQL would be WHERE text like '%quick%'
I think, the difference is, that in the filter query no scores are calculated. In the documentation:
In filter context, a query clause answers the question “Does this document match this query clause?” The answer is a simple Yes or No — no scores are calculated.
So i would use wildcard query. There you can use * for more characters and ? for only one character - depending on your needs. And here, the scores are calculated.
Related
My knowledge of Elasticsearch is a bit limited, so what I want to do might not even be possible.
Say I have an ecommerce where I want to be able to freely search on the article names and other fields, but I also want to search on exact article codes aswell. Is this possible in the same query?
Example:
"articlecode": "v400",
"name": "Earplugs for humans"
}
{
"articlecode": "b6655",
"name": "Hammer 400"
}
So can a query be written that combines both multimatch and terms? So that If I search for '400' I get 2 results, but if I search for v400 I just get one result as it is an exact match on the "articlecode"-field.
Below is our current query, where i have an ngram on the "name" field and where I use the term-keyword on the language-field.
{
"size": 10,
"query": {
"bool": {
"must": {
"multi_match": {
"query": "v400",
"fields": [
"articlecode^10",
"name^7"
]
}
},
"filter": {
"term": {
"IdLang.keyword": "sv"
}
}
}
}
}
Have you ever thought of using query_string instead of multi_match? Then you can use wildcard in your search:
{
"size": 10,
"query": {
"bool": {
"must": {
"query_string": {
"query": "*v400",
"fields": [
"articlecode^10",
"name^7"
]
}
}
}
}
}
If you want to search with 400 anywhere in the 2 fields, you can do *400*, or only leading or trailing, depending on what you want.
How do I pass a list as query string to match_phrase query?
This works:
{"match_phrase": {"requestParameters.bucketName": {"query": "xxx"}}},
This does not:
{
"match_phrase": {
"requestParameters.bucketName": {
"query": [
"auditloggingnew2232",
"config-bucket-123",
"web-servers",
"esbck-essnap-1djjegwy9fvyl",
"tempexpo",
]
}
}
}
match_phrase simply does not support multiple values.
You can either use a should query:
GET _search
{
"query": {
"bool": {
"should": [
{
"match_phrase": {
"requestParameters.bucketName": {
"value": "auditloggingnew2232"
}
}
},
{
"match_phrase": {
"requestParameters.bucketName": {
"value": "config-bucket-123"
}
}
}
]
},
...
}
}
or, as #Val pointed out, a terms query:
{
"query": {
"terms": {
"requestParameters.bucketName": [
"auditloggingnew2232",
"config-bucket-123",
"web-servers",
"esbck-essnap-1djjegwy9fvyl",
"tempexpo"
]
}
}
}
that functions like an OR on exact terms.
I'm assuming that 1) the bucket names in question are unique and 2) that you're not looking for partial matches. If that's the case, plus if there are barely any analyzers set on the field bucketName, match_phrase may not even be needed! terms will do just fine. The difference between term and match_phrase queries is nicely explained here.
I am new to elastic search and I am working with MySQL and MongoDB. I want to write the query which gives products which are active and it's name or brand_name or model_number or category contains a specific word.
Here is MySQL query.
SELECT * FROM products WHERE active=0 AND (name LIKE '%car%' OR brand_name LIKE '%car%' OR model_number LIKE '%car%' OR category LIKE '%car%');
I already tried with the below query in elastic search, but it's just AND operator.
"query": {
"bool": {
"must": [
{"match": {"active": "1"}},
{"regexp": {"name": "cars.*"}},
{"regexp": {"brand_data.brand_name": "cars.*"}},
{"regexp": {"model_number": "cars.*"}},
]
}
}
Can anyone help me to write this query in elasticsearch.
Short answer - for OR you can use should occurrence of boolean query.
Long answer with example:
It can be done in several ways, but I want point you to one detail. If you need to search only active=1 or active=0 results, it will be better to use filter occurrence in your query. It will give you better performance and caching.
The clause (query) must appear in matching documents. However unlike must the score of the query will be ignored. Filter clauses are executed in filter context, meaning that scoring is ignored and clauses are considered for caching.
So I can propose you this query:
{
"query": {
"bool": {
"filter": {
"term": {
"active": "1"
}
},
"should": [
{
"regexp": {
"name": "cars.*"
}
},
{
"regexp": {
"brand_data.brand_name": "cars.*"
}
},
{
"regexp": {
"model_number": "cars.*"
}
}
]
}
}
}
You are looking for a 'or' nested inside an 'and' clause. this is the correct format:
"query": {
"bool": {
"must": [
{"match": {"active": "1"}},
{"bool":{"should":[
{"regexp": {"name": "cars.*"}},
{"regexp": {"brand_data.brand_name": "cars.*"}},
{"regexp": {"model_number": "cars.*"}}]}}
]
}
}
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.
I'm new to elastic search. How to generate elastic search equivalent query for
select * from response where pnrno='sampleid'
I know we have to use 'filter' option in elastic search.but we do not need any ranking. (ranking can be constant) so how can I generate query for achieve this
you are correct , you can use filtered query with query clause empty and filters.Filtering a set of documents is to filter the sets upon which query acts to furthur filter/match and calculate relevance.Filters are like bool either match or reject(1/0).
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [{
"term": {
"FIELD": "VALUE"
}
}]
}
}
}
}
}
The usual way of achieving this is by using the constant_score query with an embedded term filter, like this:
{
"query": {
"constant_score": {
"filter": {
"term": {
"pnrno": "sampleid"
}
}
}
}
}