I'm using cutoff_frequency in a multi_match query with multiple fields. Is it applied to every field individually? How does it work?
This is what my code looks like.
POST beta2_index/_search
{
"_source": ["title"],
"size": 20,
"query": {
"multi_match": {
"query": "test query",
"fields": [
"title",
"description"],
"cutoff_frequency" : 0.1
}
}
}
multi_match query with option best_fields type (the default), is transformed into a dis_max query that wraps match queries, so cutoff_frequency option should be "forwarded" to every sub match queries.
See https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#type-best-fields.
The best_fields type generates a match query for each field and wraps
them in a dis_max query, to find the single best matching field.
Related
Some queries in Elasticsearch offer wildcard matching for fields with boosts, for example, the simple_query_string query.
In our use-case we would like to boost specific fields while giving all other fields a score of 0. We thought this could be achieved with the following example query pattern:
GET /kibana_sample_data_ecommerce/_search
{
"profile": "true",
"query": {
"simple_query_string": {
"query": "Eddie",
"fields": [
"*^0",
"customer_full_name^100"
]
}
}
}
It appears though that if several field definitions match the same field name via wildcards their boosts are multiplied. The above example will yield a score of 0 for all documents even if they contain the token "Eddie" in the customer_full_name field.
This following example demonstrates that the boosts are multiplied:
GET /kibana_sample_data_ecommerce/_search
{
"profile": "true",
"query": {
"simple_query_string": {
"query": "Eddie",
"fields": [
"*^0.1",
"customer_full_name^100"
]
}
}
}
It leads to the expression (customer_full_name:eddie)^10.0 in the profile explanation of the query.
Does that mean that it is not possible to achieve our desired outcome with field boosts? The desired outcome is: All matches in a specific field have theirs score multiplied by 100 while all documents with matches in other fields are still returned but have 0 score.
What I need is, elastic should search in multiple fields and return data by field priority.
For example: For the search string obil hon, elastic should search in fields[title, description, modelCaption] and return data when at first it finds Mobile Phone in Title field, then in other fields.
Query I use:
{
"from": 0,
"query": {
"bool": {
"must": [
{
"query_string": {
"default_operator": "or",
"fields": [
"title^5",
"description",
"modelCaption",
"productFeatureValues.featureValue",
"productFeatureValues.featureCaption"
],
"query": "*obil* *hone*"
}
}
]
}
},
"size": 16
}
Any suggestions?
Thanks!
You can simply use the multi-match query to query multiple fields and it supports boosting a particular field like a title in your case and different operators like OR in your case.
Sample ES query for your use case:
{
"query": {
"multi_match" : {
"query" : "mobile phones",
"fields" : [ "title^5", "description","modelCaption","productFeatureValues.featureVal"],
"fuzziness" : "AUTO" --> Adding fuzziness to query
}
}
}
Here title filed is boosted by factor 5, hence if mobile phones match in title field then it would be scored higher.
Also please note, you are using wild-card in your query string which is very costly so it's better to avoid them if you can.
EDIT: Based on OP comments, included fuzziness parameter AUTO in query for better results
How can we configure elastic search so that it only returns results which matches all the words in the search query. The documents indexed have data having multiple fields and so the words of search query may match different fields of data but all the words must get matched in the result ?
you can query string query feature to search for results
sample search query
GET /_search
{
"query": {
"query_string": {
"query": "(content:this OR name:this) AND (content:that OR name:that)"
}
}
}
In this query content and name is the field name, this is the search criteria
you can build search query similar to that.
I think you're looking for a multi_match query together with and operator. This is the link to docs: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html and it seems that cross_fieldsis query type you're looking for. I'd read more on that page, but this is probably what you are looking for:
GET /_search
{
"query": {
"multi_match" : {
"query": "Will Smith",
"type": "cross_fields",
"fields": [ "first_name", "last_name" ],
"operator": "and"
}
}
}
I have a pretty complex query and now I want to boost some documents that fulfill some criteria. I have the following simplified document structure and I try to give some documents a boost based on the id, genre, tag.
{
"id": 123,
"genres": ["ACTION", "DRAMA"],
"tags": ["For kids", "Romantic", "Nature"]
}
What I want to do is for example
id: 123 boost: 5
genres: ACTION boost: 3
tags: Romantic boost: 0.2
and boost all documents that are contained in my query and fit the criteria but I don't want to filter them out. So query clause boosting is not of any help I guess.
Edit: To make if easier to understand what I want to achieve (not sure if it is possible with elasticsearch, no is also a valid answer).
I want to search with a query and get a result set. In this set I want to boost some documents. But I don't want to enlarge the result set or filter it. The boost should be independent from the query.
For example I search for a specific tag and want to boost all documents with category 'ACTION' in the result set. But I don't want all documents with category 'ACTION' in the result set and also I don't want only documents with the specific tag AND category 'ACTION'.
I think you need to have Dynamic boosting during query time.
The first matches the id title with boost and second one matches the 'genders' ACTION.
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "id",
"boost": 5
}
}
},
{
"match": {
"content": "Action"
}
}
]
}
}
}
If you want to have multi_match match based on your query:
{
"multi_match" : {
"query": "some query terms here",
"fields": [ "id^5", "genders^3", "tags^0.2" ]
}
}
Note: the ^5 means boost for the title.
Edit:
Maybe you are asking for different types of multi_match queries (at least for ES 5.x) from the ES reference guide:
best_fields
(default) Finds documents which match any field, but uses
the _score from the best field. See best_fields.
most_fields
Finds documents which match any field and combines the _score from
each field. See most_fields.
cross_fields
Treats fields with the same analyzer as though they were one big
field. Looks for each word in any field. See cross_fields.
phrase
Runs a match_phrase query on each field and combines the _score from
each field. See phrase and phrase_prefix.
phrase_prefix
Runs a match_phrase_prefix query on each field and combines the _score
from each field. See phrase and phrase_prefix.
More at: ES 5.4 ElasticSearch reference
I found a solution and it was pretty simple. I use a boosting query. I now just nest the different boosting criteria with and my original query is now the base query.
https://www.elastic.co/guide/en/elasticsearch/reference/2.3/query-dsl-boosting-query.html
For example:
{
"query": {
"boosting": {
"positive": {
"boosting": {
"positive": {
"match": {
"director": "Spielberg"
}
},
"negative": {
"term": {
"genres": "DRAMA"
}
},
"negative_boost": 1.3
}
},
"negative": {
"term": {
"tags": "Romantic"
}
},
"negative_boost": 1.2
}
}
}
I have a database with entries like
title: This is my awesome title
abstract: A more detailed descriptions of what [...]
I would like to build an Elasticsearch query that matches the above document with, e.g.,
awe detai
In words: A multi_match phrase_prefix query with multiple search terms. (This is intended to be used as a search-as-you-type feature.)
I see how you can combine multi_match and phrase_prefix, but it's unclear to me how to do this for multiple search terms.
Any hints?
Well there is few ways to do that
POST stack/autocomplete/1
{
"title": "This is my awesome title",
"abstract": "A more detailed descriptions of what"
}
Then you can search using query string with star but problem here is that you need to append asterix to query
POST stack/autocomplete/_search
{
"query": {
"query_string": {
"fields": [
"title",
"abstract"
],
"query": "awe* detai*"
}
}
}
If you want to match on user query then you can use like that
POST stack/autocomplete/_search
{
"query": {
"multi_match": {
"fields": [
"title",
"abstract"
],
"query": "awesome tit",
"type": "phrase_prefix"
}
}
}
One more option to consider would be to use nGram with query string so you will not need to modify user query "awe* detai*"