How to implement 'Starts with' search in elasticsearch 2.x - elasticsearch

I have a requirement where I need to return only those records whose comments donot start with a String. PFB the query and this approach is not working. Need help
{
"size": 0,
"fields": ["id","comment"],
"query": {
"bool": {
"must_not": [
{
"wildcard": {
"comment":
"AG//*"
}
}
]
}
}
}

First, you should remove the "size": 0 from your query (or set the required size) to see the results.
Now, the best way to implement 'Starts with' in elasticsearch is by using the Prefix Query as follows:
{
"fields": ["id", "comment"],
"query": {
"bool": {
"must_not": [
{
"prefix": {
"comment": "AG" <-- No need for any wildcards
}
}
]
}
}
}
Note: The Prefix Query and Wildcard Query makes sense only on not_analyzed fields, so make sure your "comment" field has the same mapping.

Related

Many must with multi_match

I have this query:
{
"query": {
"bool": {
"must": [
{
"match": {
"egyik": {
"query": "piros alma"
}
}
},
{
"match": {
"masik": {
"query": "piros alma"
}
}
}
]
}
}
}
It's not too beautiful, because the query parameter occured twice, therefore I tried to rewrite it with the multi_match syntax:
{
"query": {
"bool": {
"must": {
"multi_match": {
"query": "piros alma",
"fields": [
"egyik",
"masik"
]
}
}
}
}
}
But it returns more hits than the first. I tried operator, minimum_should_match modifiers, but not helps. How do I solve the same result with multi_match?
As far as I know, all types of multi-match queries return a hit when the provided query matches any of the listed fields (see Elastic docs). Therefore, the reason why you have more hists with multi_match is that you can't enforce the same boolean condition you have with your first query. That said, I don't see anything wrong with repeating the same query parameter twice. If you want to generalise it a bit, you might want to consider using Search Templates
By default operator OR is used, which means query term can be present in any field, if you want query term to be present in all the fields then you can explicitly define operator field with AND value.
{
"query": {
"bool": {
"must": {
"multi_match": {
"query": "piros alma",
"fields": [
"egyik",
"masik"
],
"operator":"and"
}
}
}
}
}
To know more you can go through this
Meanwhile I found the solution:
{
"query": {
"bool": {
"must": {
"multi_match": {
"query": "piros alma",
"fields": [
"egyik",
"masik"
],
"type": "cross_fields",
"operator": "and"
}
}
}
}
}
Need the type and operator together.

Elasticsearch filter with multi_match

I'm trying to write a query in ElasticSearch where I combine multi_match with filter for an id or a number og ids.
This is what i have so far:
{
"query": {
"bool": {
"must": {
"multi_match": {
"query": "Kasper",
"fields": ["name", "first_name", "last_name"]
}
},
"filter": {
"term": {
"user_id": "ea7528f0-1b8a-11e8-a492-13e39bbd17cb"
}
}
}
}
}
The "must" part of the query works perfectly, and when I run it alone, I get two results.
When I pick out the "user_id" from one of the two results and adds the "filter" part of the query with that id, I get nothing.
What I really want to do is have something like in SQL where user_id in ('id1', 'id2'), so the filtering would be something like:
...,
"filter": {
"terms": {
"user_id": ["ea7528f0-1b8a-11e8-a492-13e39bbd17cb"]
}
}
Did I misunderstand something here?
I'm guessing that this is because user_id field is treated as a text and is analyzed. You should use keyword type in this situation (you need just change the mapping of user_id field.
Another way (if you are on Elasticsearch 5+) you can search in keyword subfield. Just try use below query:
{
"query": {
"bool": {
"must": {
"multi_match": {
"query": "Kasper",
"fields": ["name", "first_name", "last_name"]
}
},
"filter": {
"term": {
"user_id.keyword": "ea7528f0-1b8a-11e8-a492-13e39bbd17cb"
}
}
}
}
}
I only changed "user_id" to "user_id.keyword" in your query.

To find the distinct fields in an elastic search query

I need the values of only one field and there are duplicate values in it.
POST _search
{
"query": {
"bool": {
"must": [
{"term": {
"report": {
"value": "some_value"
}
}}
]
}
},
"fields": [
"field_name"
]
}
I need only the distinct values of field_name.
What if you have your query, with the use of terms aggregation and then by applying a top_hits aggregation in order to narrow down to the single value which you wanted to achieve:
"aggs": {
"values": {
"terms": {
"field": "your_field"
}
}
}
This SO could be helpful as well.

ElasticSearch multi_match if field exists apply filter otherwise dont worry about it?

So we got an elasticsearch instance, but a job is requiring a "combo search" (A single search field, with checkboxes for types across a specific index)
This is fine, I simply apply this kind of search to my index (for brevity: /posts):
{
"query": {
"multi_match": {
"query": querystring,
"type":"cross_fields",
"fields":["title","name"]
}
}
}
}
As you may guess from the need for the multi_match here, the schemas to each of these types differs in one way or another. And that's my challenge right now.
In one of the types, just one, there is a field that doesnt exist in the other types, it's called active and it's a basic boolean 0 or 1.
We want to index inactive items in the type for administration search purposes, but we don't want inactive items in this type to be exposed to the public when searching.
To my knowledge and understanding, I want to use a filter. But when I supply a filter asking for active to be 1, I only ever now get results from that type and nothing else. Because now it's explicitly looking for items with that field and equal to one.
How can I do a conditional "if field exists, make sure it equals 1, otherwise ignore this condition"? Can this even be achieved?
if field exists, make sure it equals 1, otherwise ignore this condition
I think it can be implemented like this:
{
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"exists": {
"field": "active"
}
},
{
"term": {
"active": 1
}
}
]
}
},
{
"missing": {
"field": "active"
}
}
]
}
}
}
}
}
and the complete query:
{
"query": {
"filtered": {
"query": {
"multi_match": {
"query": "whatever",
"type": "cross_fields",
"fields": [
"title",
"name"
]
}
},
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"exists": {
"field": "active"
}
},
{
"term": {
"active": 1
}
}
]
}
},
{
"missing": {
"field": "active"
}
}
]
}
}
}
}
}

Minimum should match on filtered query

Is it possible to have a query like this
"query": {
"filtered": {
"filter": {
"terms": {
"names": [
"Anna",
"Mark",
"Joe"
],
"execution" : "and"
}
}
}
}
With the "minimum_should_match": "2" statement?
I know that I can use a simple query (I've tried, it works) but I don't need the score to be computed. My goal is just to filter documents which contains 2 of the values.
Does the score generally heavily impact the time needed to retrieves document?
Using this query:
"query": {
"filtered": {
"filter": {
"terms": {
"names": [
"Anna",
"Mark",
"Joe"
],
"execution" : "and",
"minimum_should_match": "2"
}
}
}
}
I got this error:
QueryParsingException[[my_db] [terms] filter does not support [minimum_should_match]]
Minimum should match is not a parameter for the terms filter. If that is the functionality you are looking for, I might rewrite your query like this, to use the bool query wrapped in a query filter:
{
"filter": {
"query": {
"bool": {
"should": [
{
"term": {
"names": "Anna"
}
},
{
"term": {
"names": "Mark"
}
},
{
"term": {
"name": "Joe"
}
}
],
"minimum_should_match": 2
}
}
}
}
You will get documents matching preferably exactly all three, but the query will also match document with exactly two of the three terms. The must is an implicit and. We also do not compute score, as we have executed the query as a filter.

Resources