ElasticSearch phrase search not working for wildcard search - elasticsearch

I have a word index and I can't search phrases on elasticsearch. there is no result. I check tons of solutions but I can't implement them to my query.
My mapping looks like this;
PUT /words/_mapping
{
"properties": {
"text": {
"type": "keyword"
}
}
}
(if the type is text everything worked as expected)
My elastic query looks like this;
GET /words/_search
{
"from": 0,
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"query_string": {
"default_field": "text",
"default_operator": "AND",
"query": "*foo bar baz*"
}
}
]
}
}
]
}
},
"size": 100,
"track_total_hits": true
}
But there is no data
_id
_index
_score
_type
text
I expect the record that has `foo bar baz` value,
_id
_index
_score
_type
text
drDzzYQBu3ncIuw4vn10
words
0.0
_doc
foo bar baz
What is the problem? Could someone help?

"Query_string" is a full text query and will be optimized for text fields only , I suggest you to to use text type instead of keyword for this query.
As you are using AND operator , it will treat as phrase only.

Related

How does multi field mapping work in Elastic Search

I want to support both text search (match query) as well as exact match (term query) on a single field in my elasticsearch index.
Following is the mapping that I have created:
PUT multi_mapping_test/_mapping
{
"properties": {
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
However, the term query is not behaving as I am expecting it to (may be understanding of it is wrong).
For example, here are couple of sample documents indexed:
POST multi_mapping_test/_doc
{
"name": "abc llc"
}
POST multi_mapping_test/_doc
{
"name": "def llc"
}
Following term query yields no results:
GET multi_mapping_test/_search
{
"query": {
"term": {
"name": {
"value": "abc llc"
}
}
}
}
Am I doing anything wrong or is my understanding of exact matches with term query incorrect?
P.S. The term query works fine when I put mapping for only keyword type.
Term query: Returns documents that contain an exact term in a provided field.
When you're searching for exact match you should use keyword field types. Like the following:
GET multi_mapping_test/_search
{
"query": {
"term": {
"name.keyword": {
"value": "abc llc"
}
}
}
}
In addition, You can use bool query for both text search (match query) and exact match (term query) in your elasticsearch index.
GET multi_mapping_test/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": "abc llc"
}
},
{
"term": {
"name.keyword": {
"value": "abc llc"
}
}
}
],
"minimum_should_match": 1
}
}
}
Note: You can also use the match_bool_prefix query if you need to autocomplete the feature.
Details: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-bool-prefix-query.html
"abc llc" _score will be higher than "def llc" because it matches both match and term queries.

Elasic search: find doc by id and highlight words based on query string

I like to find an document in elastic search an highlight terms based on an query string.
Is this possible?
I tried to run an query-string elastic search and filter the result based on ID. But those sounds not very efficient, because elastic first generates an huge list of all document matched the querystring (which could by millions) an pic only one document based on the filter.
Is there a way or query-contstruct to combine querystring and "search for term in _id field" in one boolean search?
Something like this (which is not working):
"query": {
"bool": {
"must": {
"query_string": {
"query": "red*",
"fields": [
"text",
"title"
]
},
"term": {
"_id":"fda72434fa172"
}
}
}
},
"highlight": {
"fields": {
[...]
I made a small example that can be a starting point.
Use filter to perform your query and retrieve the doc by id.
Then I used match and highlight to highlight the term I want.
POST test/_doc/fda72434fa172
{
"text": "I like to find an document in elastic search an highlight terms based on an query string. Is this possible?"
}
GET test/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"_id": "fda72434fa172"
}
}
],
"must": [
{
"match": {
"text": {
"query": "elastic search"
}
}
}
]
}
},
"highlight": {
"fields": {
"text": {}
}
}
}

Elasticsearch 6.3 query with space in a keyword field and not returning all documents

I have the fallowing part of a mapping:
"name": {
"store": "true",
"type": "keyword"
}
and this query:
{
"query":{
"query_string":{
"query":"+(name:John Doe)",
"fields":[
]
}
},
"aggregations":{
"name":{
"terms":{
"field":"name",
"size":10
}
}
}
}
The query should return over 100 results however it only returns a few. If I add quotes to John Doe like this: \"John Doe\" then it returns all the desired results.
I'm wondering why this happens. Isn't enough that the field is mapped as keyword so that John Doe is analyzed as a whole, and no quotes should be added? Also, why would it return less items without quotes?
Note: In ES 1.4 the same query seems to work fine (although is not the same data to be honest, and it uses facets instead of aggregations).
The documentation for query string query clearly states:
If the field is a keyword field the analyzer will create a single term ...
So you don't need to add quotes to your search string. Instead, you need to write your query correctly. Currently your query try to find the term John in field name, and term Doe in all other fields! So you must rewrite your query in one of the following ways:
Add parentheses to your search term so the query parser can "understand" that all words must be found in name field:
{
"query": {
"query_string": {
"query": "+(name:(John Doe))",
"fields": [
]
}
},
"aggregations": {
"name": {
"terms": {
"field": "name",
"size": 10
}
}
}
}
Specify field name in fields array rather than in query string:
{
"query": {
"query_string": {
"query": "+(John Doe)",
"fields": [
"name"
]
}
},
"aggregations": {
"name": {
"terms": {
"field": "name",
"size": 10
}
}
}
}

How can Elasticsearch search characters like #

I face the problem about writing Elasticsearch query.
My query is like below
{
"query": {
"query_string": {
"default_field": "content",
"query": "#lin1"
}
},
"from": 0,
"size": 1000,
"sort": [
{
"time": "desc"
}
]
}
And I am using query_string
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html
But the # character can not match.
It will come out this kind of result: lin1 or 「lin1」
So how should I write the Elasticsearch query to match #lin1?
It all depends on the analyzer you are using. For all you know, you are using the standard analyzer which discards the '#' symbol from the index. In that case, you'll never be able to search for the '#' symbol. But if that is not the case and you do have '#' indexed, you can modify the query_string section of your query to below:
"query_string": {
"default_field": "content",
"query": "#lin1",
"analyzer": "whitespace"
}

Elasticsearch: how to disable scoring on a field?

I am new to Elasticsearch and please forgive me if the answer is obvious.
Here is what I have for the mapping of the field in question:
"condition" : { "type" : "string", "store" : "no", "index": "not_analyzed", "omit_norms" : "true" }
I need search on this field, but I need 100% string match (no stemming, etc.) on a sub-string (blank separated). An example of this field in a document is as follows:
{
"condition": "abc xyz"
}
An example query is:
/_search?q=condition:xyz
Is the above mapping correct? I also used omit_norms (true). Is this a correct thing to do in my case?
How can I disable scoring on this field? Can I do it in mapping? What is the best way of doing it? (Actually I need to disable scoring on more than one. I do have fields that need scoring)
Thanks and regards!
Using omit_norms:true will not take the length of the field into consideration for the scoring, Elasticsearch won't index the norms information. So if you don't want to use scoring that is a good thing to do as it will save you some disk space.
If you're not interested in scoring in your queries use a filtered query:
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": {
"term": {
"condition": "abc xyz"
}
}
}
}
}
}
}
The new syntax for a filtered query is now:
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"term": {
"condition": "abc"
}
}
}
}
}

Resources