ElasticSearch : MultiMatch with "match a list of values" - elasticsearch

How can I combine MultiMatch + "match a list of values" in a single query.
ie . I want to query a list of names ["John","Bas","Peter"] against a list of fields ["first_name","Alias","nick_name","surname"]
-match a list of values-
{
"query": {
"filtered" : {
"filter" : {
"terms": {
"first_name": ["John","Bas","Peter"]
}
}
}
}
}
-MultiMatch-
{
"multi_match" : {
"query": "john",
"fields": ["first_name","Alias","nick_name","surname"]
}
}

You can provide multiple search terms to the multi_match as well:
"query": {
"multi_match": {
"query": "John Bas Peter",
"fields": [
"first_name",
"Alias",
"nick_name",
"surname"
]
}
}
Also, multi_match has various ways by which it's actually transforming internally the query: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#multi-match-types
If you use the _validate API with this you could see how exactly ES is re-interpreting the query:
GET /_validate/query?explain=true
{
"query": {
"multi_match": {
"query": "John Bas Peter",
"fields": [
"first_name",
"Alias",
"nick_name",
"surname"
]
}
}
}
The above gives:
"explanations": [
{
"index": "test",
"valid": true,
"explanation": "((Alias:john Alias:bas Alias:peter) | (surname:john surname:bas surname:peter) | (nick_name:john nick_name:bas nick_name:peter) | (first_name:john first_name:bas first_name:peter))"
}
]

Related

How to apply fuzziness in a multi_match query to only specified fields in elasticsearch?

If I have a search query like below:
query: {
multi_match: {
query: searchQry,
fields: ["field1", "field2", "field3"],
fuzziness: 2,
fuzzy_transpositions: true,
},
},
How am I able to apply fuzziness only on selective fields such as "field1" or "field2" or "field1" and "field3" instead of all of them, which is the standard behaviour?
Using MultiMatch is not possible.
You can mix multi-match with matches with separated fuzziness.
Example:
{
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "xpto",
"fields": [
"field1",
"field2"
]
}
},
{
"match": {
"fiedl1": {
"query": "xpto",
"fuzziness": 1
}
}
},
{
"match": {
"fiedl2": {
"query": "xpto",
"fuzziness": 2
}
}
}
]
}
}
}

How to filter the follwing query in elasticsearch?

I am using the following search:
{
"_source": [
"title",
"bench",
"court",
"id_"
],
"size": 10,
"query": {
"bool": {
"must": {
"multi_match": {
"query": "murder"
,
"fields": [
"title",
"content"
]
}
},
"should": {
"multi_match": {
"query": "murder",
"fields": [
"title.standard",
"content.standard"
]
}
}
}
},
"highlight": {
"fields": {
"title": {},
"content": {}
}
}
}
I now want to filter the results using the id (_id) elastic search gave it during indexing. For example, {"_id" : 5903}. I guess you have to use the term query. The results should be such that only if the _id is matched, the document returns. How can I do that?
In order to get your query filtered by doc's id (one, or many), there is a special id query in elasticsearch. Here are the details: https://www.elastic.co/guide/en/elasticsearch/reference/master/query-dsl-ids-query.html

Querying fields with AND in ElasticSearch

In my ElasticSearch document index I have a property type like
type= LOCATION | PERSON | TIME
and a text field that represents the whole document.
To search for types like LOCATION and a specific text like `Mountain View" I do like
doc.text:Mountain View AND doc.type:LOCATION
If I want to do a OR query I would use instead the query_string approach like
"query": {
"query_string": {
"query": "entity.text: (Mountain View OR Menlo Park) AND entity.type:LOCATION"
}
}
This works as well. To do AND queries, like searching for item.text having both "Mountain View" and "Menlo Park" for a item.type=LOCATION, it does not work doing like
"query": {
"query_string": {
"query": "entity.text: (California AND Nevada) AND entity.type:LOCATION"
}
}
Other attempts were:
Using bool clause with should like:
{
"query": {
"bool": {
"should": [
{ "match": { "text": "Menlo Park" }},
{ "match": { "text": "Mountain View" }}
]
}
}
}
Using cross-fields with multi_match
"query": {
"multi_match": {
"query": "California Nevada",
"type": "cross_fields",
"operator": "AND",
"fields": [
"text"
]
}
}
Another approach was using must with the latter (in this case omitting the type by the way):
{
"query": {
"bool": {
"must": [
{
"multi_match" : {
"query": "Nevada",
"type": "cross_fields",
"fields": [ "text"],
}
},
{
"multi_match" : {
"query": "California",
"type": "cross_fields",
"fields": [ "text" ]
}
}
]
}
}
}
but it returns no results neither. Note that in the last case using should instead of must will produce an OR query that will work ok.
So how to perform an AND query on the same field text to match multiple values like California and Nevada?
If I understood the question right, I would do the following:
{
"query": {
"bool" : {
"must": [
"match" : {
"text" : {
"query" : "California Nevada",
"operator" : "and"
}
}
]
}
}
}
Documentation
Hope it helps!

Searching in specific fields of types

Consider the following query:
{
"query" : {
"match_phrase" : {
"_all" : "Smith"
}
}
}
How would I specify in which fields of which types it may search, instead of searching in everything? (field names may be non-unique across types)
I've tried the query below, but it didn't work (it doesn't return results, it does when I remove person. from all fields):
{
"query": {
"multi_match": {
"query": "Smith",
"fields": [
"person.first_name",
"person.last_name",
"person.age"
],
"lenient": true
}
}
}
I'm sending these queries to http://localhost:9200/tsf-model/_search.
If you can build your query dynamically, I think you can use a combination of your multi_match query and a type query for each type, in order to achieve what you want:
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"filter": [
{
"type": {
"value": "type1"
}
},
{
"multi_match": {
"query": "Smith",
"fields": [
"field1",
"field3",
"field5"
]
}
}
]
}
},
{
"bool": {
"filter": [
{
"type": {
"value": "type2"
}
},
{
"multi_match": {
"query": "Smith",
"fields": [
"field2",
"field4",
"field6"
]
}
}
]
}
}
]
}
}
}

Override search requirement in Elasticsearch

We search on the following fields in our index:
individual_name (string)
organisation_name (string)
profile (string)
locations (string)
nationwide (boolean)
If a user searches for "optometrist" in "Hamilton", and an optometrist in our index has listed themselves as "nationwide" (but not specifically in Hamilton), desired behaviour is that the optometrist would show up with the Hamilton results - effectively ignoring the location requirement.
We're currently running a multi_match query, an example of which is below.
{
"query": {
"filtered" : {
"query" : {
"multi_match": {
"query": "optometrist",
"zero_terms_query": "all",
"operator": "and",
"fields": [
"individual_name^1.2",
"organisation_name^1.5",
"profile",
"accreditations"
]
}
},
"filter": {
"and": [{
"term": {
"locations" : "hamilton"
}
}],
}
}
}
}
How can this be modified so documents with "nationwide": "yes" are returned for this query, regardless of location?
I've tried an or query under the and, but of course that ignored the multi_match.
I think this will give you the desired results:
{
"query": {
"filtered" : {
"query" : {
"multi_match": {
"query": "optometrist",
"zero_terms_query": "all",
"operator": "and",
"fields": [
"individual_name^1.2",
"organisation_name^1.5",
"profile",
"accreditations"
]
}
},
"filter": {
"or": [
{"term": {"locations" : "hamilton"}},
{'term' : {'nationwide' : 'yes'}}
],
}
}
}
}

Resources