highlight does not properly work with exact phrase match search in elasticsearch - elasticsearch

I am having problem with highlighting the exact phrase search. when the highlight comes back it highlights all the terms regardless of the exact search. see the example:
Put /test2
PUT /test2/all/1
{
"name" : "climate behaviour change"
}
PUT /test2/all/3
{
"name" : "climate behaviour change it is climate change"
}
and my mapping:
{
"test2": {
"mappings": {
"all": {
"properties": {
"name": {
"type": "string"
}
}
}
}
}
}
and when I run this query:
GET /test2/_search
{
"query": {
"query_string": {
"fields": ["name"],
"query": "\"climate change\""
}
}
,"highlight": {
"fields": {
"name": {"number_of_fragments": 0}
}
}
}
the result is
"hits": [
{
"_index": "test2",
"_type": "all",
"_id": "3",
"_score": 0.23013961,
"_source": {
"name": "climate behaviour change it is climate change"
},
"highlight": {
"name": [
"<em>climate</em> behaviour <em>change</em> it is <em>climate</em> <em>change</em>"
]
}
}
]
since I searched for exact climate change I would expect to have highlight for just the second part of the result, so climate behaviour change should not get highlighted. Does anyone know why this is like that?
or any other way I can get what I want?

By Default query_string uses OR operator see here
Rather use AND operator.
GET /test2/_search
{
"query": {
"query_string": {
"fields": ["name"],
"query": "\"climate change\"",
"default_operator": AND
}
}
,"highlight": {
"fields": {
"name": {"number_of_fragments": 0}
}
}
}

Related

ElasticSearch - Search if this term include in the list index or not?

It was mapped like this:
"parent_ids": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
The actual data looks like this:
parent_ids = ["asdf", "aeraeg", "A123"]
I want to filter all products with parent_ids "A123":
"filter":
{
"match": {
"parent_ids": "{{parent_ids}}"
}
}
But not working
You can use terms query that returns documents that contain one
or more exact terms in a provided field.
Search Query:
{
"query": {
"terms": {
"parent_ids.keyword": [ "A123"]
}
}
}
Search Result:
"hits": [
{
"_index": "64745756",
"_type": "_doc",
"_id": "1",
"_score": 1.0,
"_source": {
"parent_ids": [
"asdf",
"aeraeg",
"A123"
]
}
}
]
Search Query using bool query:
{
"query": {
"bool": {
"filter": {
"match": {
"parent_ids": "A123"
}
}
}
}
}
If you need to format your query to support a JSON array in parameters, you'll need to format your query like this:
{
"terms": {
"parent_ids.keyword": {{#toJson}}parent_ids{{/toJson}}
}
}
Note that the match query doesn't support an array of values, only the terms query does.

Matching the stored values and queries in Elastic Search

I have a field called that is inside a nested field "name" that is a "Keyword" in elastic search.
Name field contains 2 values.
Jagannathan Rajagopalan
Rajagopalan.
If I query "Rajagopalan", I should get only the item #2.
If I query the complete Jagannathan Rajagopalan, I should get #1.
How do I achieve it?
You need to use the term query which is used for exact search. Added a working example according to your use-case.
Index mapping
{
"mappings": {
"properties": {
"name": {
"type": "nested",
"properties": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
Index sample docs
{
"name" : {
"keyword" : "Jagannathan Rajagopalan"
}
}
And another doc
{
"name" : {
"keyword" : "Jagannathan"
}
}
And search query
{
"query": {
"nested": {
"path": "name",
"query": {
"bool": {
"must": [
{
"match": {
"name.keyword": "Jagannathan Rajagopalan"
}
}
]
}
}
}
}
}
Search result
"hits": [
{
"_index": "key",
"_type": "_doc",
"_id": "2",
"_score": 0.6931471,
"_source": {
"name": {
"keyword": "Jagannathan Rajagopalan"
}
}
}
]

search array of strings by partially match in elasticsearch

I got fields like that:
names: ["Red:123", "Blue:45", "Green:56"]
it's mapping is
"names": {
"type": "keyword"
},
how could I search like this
{
"query": {
"match": {
"names": "red"
}
}
}
to get all the documents where red is in element of names array?
Now it works only with
{
"query": {
"match": {
"names": "red:123"
}
}
}
You can add multi fields OR just change the type to text, to achieve your required result
Index Mapping using multi fields
{
"mappings": {
"properties": {
"names": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
Adding a working example with index data, mapping, search query, and search result
Index Mapping:
{
"mappings":{
"properties":{
"names":{
"type":"text"
}
}
}
}
Index Data:
{
"names": [
"Red:123",
"Blue:45",
"Green:56"
]
}
Search Query:
{
"query": {
"match": {
"names": "red"
}
}
}
Search Result:
"hits": [
{
"_index": "64665127",
"_type": "_doc",
"_id": "1",
"_score": 0.2876821,
"_source": {
"names": [
"Red:123",
"Blue:45",
"Green:56"
]
}
}
]

Returning documents that match multiple wildcard string queries

I'm new to Elasticsearch and would greatly appreciate help on this
In the query below I only want the first document to be returned, but instead both documents are returned. How can I write a query to search for two wildcard strings on two separate fields, but only return documents that match?
I think what's being returned currently is score dependent, but I don't need the score.
POST /pr/_doc/1
{
"type": "Type ONE",
"currency":"USD"
}
POST /pr/_doc/2
{
"type": "Type TWO",
"currency":"USD"
}
GET /pr/_search
{
"query": {
"bool": {
"must": [
{
"simple_query_string": {
"query": "Type ON*",
"fields": ["type"],
"analyze_wildcard": true
}
},
{
"simple_query_string": {
"query": "US*",
"fields": ["currency"],
"analyze_wildcard":true
}
}
]
}
}
}
Use below query which uses the default_operator: AND and query string for in depth information and further reading.
Search query
{
"query": {
"query_string": {
"query": "(Type ON*) AND (US*)",
"fields" : ["type", "currency"],
"default_operator" : "AND"
}
}
}
Index your sample docs and it returns your expected doc only:
"hits": [
{
"_index": "multiplequery",
"_type": "_doc",
"_id": "1",
"_score": 2.1823215,
"_source": {
"type": "Type ONE",
"currency": "USD"
}
}
]

Elasticsearch OR filtered query does not return results

I have the following data set:
{
"_index": "myIndex",
"_type": "myType",
"_id": "220005",
"_score": 1,
"_source": {
"id": "220005",
"name": "Some Name",
"type": "myDataType",
"doc_as_upsert": true
}
}
Doing a direct match query like so:
GET typo3data/destination/_search
{
"query": {
"match": {
"name": "Some Name"
}
},
"size": 500
}
Will return the data just fine:
"hits": {
"total": 1,
"max_score": 3.442347,
"hits": [...
Doing an OR-query however (I am not sure which syntax is correct, the first syntax is taken from elasticsearch docs, the second is a working query taken from another project with the same versions):
GET typo3data/destination/_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"or": {
"filters": [
{
"term": {
"name": "Some Name"
}
}
]
}
}
}
},
"size": 500
}
or
{
"query":
{
"match_all": {}
},
"filter":
{
"or":
[
{ "term": { "name": "Some Name"} },
{ "term": { "name": "Some Other Name"} }
]
},
"size": 1000
}
Does not return anything.
The mapping for the name field is:
"name": {
"type": "string",
"index": "not_analyzed"
}
Elasticsearch version is 1.4.4.
When indexing "some name" , this is broken into tokens as follows -
"some name" => [ "some" , "name" ]
Now in a normal match query , it also does the same above process before matching result. If either "same" or "name" is present , that document is qualified as result
match query ("some name") => search for term "some" or "name"
The term query does not analyze or tokenize your query. This means that it looks for a exact token or term of "some name" which is not present.
term query ("some name") => search for term "some name"
Hence you wont be seeing any result.
Things should work fine if you make the field not_analyzed , but then make sure the case is also matching,
You can read more about the same here.
After extending our mapping to include every field we have:
PUT typo3data/_mapping/destination
{
"someType": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string",
"index": "not_analyzed"
},
"parentId": {
"type": "integer"
},
"type": {
"type": "string"
},
"generatedUid": {
"type": "integer"
}
}
}
}
The or-filters were working. So the general answer is: If you have such a problem, check your mappings closely and rather do too much work on them than too little.
If someone has an explanation why this might be happening, I will gladly pass the answer mark on to it.

Resources