prefixQuery in Elastic search not working - elasticsearch

{
"from": 0,
"size": 100,
"timeout": "10m",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"bool": {
"filter": [
{
"bool": {
"must": [
{
"term": {
"input.custom_attrs.index": {
"value": "1",
"boost": 1
}
}
}
]
}
},
{
"bool": {
"must": [
{
"prefix": {
"input.custom_attrs.value": {
"value": "An*",
"boost": 1
}
}
}
]
}
}
]
}
}
]
}
}
]
}
}
}
Explanation -
I want to search the field with "An" as prefix .
Also i am sure that there is data with value "Annual" and "Annual Fund" ,which should appears in all match search .
But these records are not appearing with prefix query as given above.I tried with regexp query and wildcard query too .But they are also not working .Please give your valuable suggestions how to make the query working.

Possible causes why it's not working
look like while indexing data you used the default mapping or text field, which uses the default standard analyzer which converts the generated tokens to lowercase.
While prefix queries are not analyzed and search term doesn't go through any analyzer and will not be lowercased.
In your case, you are searching for An, note capital A, while for Annual and Annual fund, tokens would be annual and annual and fund, hence its not matching.
Solution:
Please use an as your prefix query and you should get your search results.

Related

Elasticsearch Range greater than or field does not exist

So the problem is something like this I want to get posts that whose online field is greater than a time or the field does not exist and I only want to use these two clauses as a filtering mechanism i.e. they should not contribute any score towards the search and there are other clauses that do the actual searching.
Here is what I currently have
{
"query": {
"bool": {
"should": [
{"range" : {"online" : {"gte" : time}}},
{"bool": {"must_not": {"exists": {"field": "online"}}}}
],
}
}
}
The problem is I think these are contributing to the score. If a doc where the online field is greater than time it gets a score of 1.0 and if there is a doc where the online field is not present it gets a score of 0.0
You can wrap your bool should query inside the bool filter clause. In the filter clause the scoring is ignored, so the score from the range or should will not contribute any score towards the search. Modify your query as
{
"query": {
"bool": {
"filter": {
"bool": {
"should": [
{
"range": {
"online": {
"gte": 6
}
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "online"
}
}
}
}
]
}
}
}
}
}

Assign custom scores to clauses in boolean query in Elasticsearch

In Elasticsearch I am testing the following query:
GET sdata/_search
{
"query": {
"bool": {
"must": [
{ "match": { "f1": "sth" } }
],
"should": [
{ "match": { "f2": "sth" } }
]
}
}
}
I know that the overall score of retrieved documents depends on the number of matches they achieve. but is it possible to customize the final score so that the documents that match the should clause may be weighted much more higher than documents that match the must alone? can I add a script to determine how each clause contribute to the final score?
Thank you in advance
You can use a boost parameter along with the should clause
{
"query": {
"bool": {
"must": [
{
"match": {
"f1": "sth"
}
}
],
"should": [
{
"match": {
"f2": {
"query": "sth",
"boost": 10
}
}
}
]
}
}
}

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

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.

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.

May I search among some fields, but use another field's matching score for sorting?

I have some documents like this
{"id":1,"city":"London","content":"soccer","continent":"Europe"},
{"id":2,"city":"New York","content":"basketball","continent":"North America"},
{"id":3,"city":"Tokyo","content":"baseball","continent":"Asia"},
...
I need to search keywords among some fields(excluding city field), e.g. a query like
{
"query": {
"bool": {
"should": [ //SHOULD_CLAUSE
"match": {
"continent": "America"
},
"term": {
"content": "soccer"
}
]
}
}
}
To make the results more "personalized", I want to make matched documents whose city field is the same as the visiting user's city property.
However, if I make city as a query field(something like "match":{"city":"Tokyo"}) in should boolean clause, it may return some documents that only match the city field, which mismatch the fields I need to search. When using boost to make city field more "important" for sorting things goes worse.
How can I achieve my goal?
It seems that a possible way write the SHOULD_CLAUSE part twice and make one of it combined with city clause using and
{
"query": {
"bool": {
"should": [{
"bool": {
"must": [{
"bool": {
SHOULD_CLAUSE
}
}, {
"match": {
"city": {
"query": "Tokyo",
"boost": 4.0
}
}
}]
}
}, {
"bool": {
SHOULD_CLAUSE
}
}]
}
}
}
But under the real circumstance the SHOULD_CLAUSE part may be more complicated and the whole query seems too long to write. I wonder if there is a better way.
If you want to have only result matching your user city, you should wrap your should query into a must query, something like :
{
"query": {
"bool": {
"must": [{
"bool": {
"should": [{
SHOULD_CLAUSE_1
}, {
SHOULD_CLAUSE_2
}]
}
}, {
"match": {
"city": "Tokyo"
}
}]
}
}
}

Resources