Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What match_none is useful for?

I looked through the docs and other references and cannot understand in what situation the match_none query can be useful?

I suspect it can be handy in some bool queries perhaps? On its own, it seems odd.

References:

  • https://github.com/elastic/elasticsearch/issues/17540
  • https://github.com/elastic/elasticsearch/issues/13406
  • https://github.com/elastic/elasticsearch/pull/14435
like image 669
Datageek Avatar asked Nov 04 '17 09:11

Datageek


3 Answers

Too long to post it in comments, sorry for the spam answer :/

I used it in a filter with minimum should match to handle non relevant words myself, without elastic search ("non relevant" words depending of the context).

Example, looking in an artist index AND an artwork index and rendering the most pertinent of the searches to the user the following sentence :

"An artwork blue"

artwork is not a relevant word to search in the artist index (it will match a lot of noise with biography, comments and so but is a non-sense) except if the user is looking for an artist named "Artwork".

My filter for artist index looked (in a way more complicated way) like this :

{
    "query": {
        "bool": {
            "should": [{
                    "query": {
                        "bool": {
                            "should": [{
                                "match": {
                                    "name": "An"
                                }
                            }, {
                                "match": {
                                    "biography": "An"
                                }
                            }]
                        },
                        "minimum_should_match": "100%"
                    }
                },
                {
                    "query": {
                        "bool": {
                            "should": [{
                                "match": {
                                    "name": "artwork"
                                }
                            }, {
                                "match_none": {                                 
                                }
                            }]
                        },
                        "minimum_should_match": "100%"
                    }
                },
                {
                    "query": {
                        "bool": {
                            "should": [{
                                "match": {
                                    "name": "blue"
                                }
                            }, {
                                "match": {
                                    "biography": "blue"
                                }
                            }]
                        },
                        "minimum_should_match": "100%"
                    }
                }
            ],
            "minimum_should_match": "100%"
        }
    }
}

As it is dynamically built (with a dynamic minimum should match) and can in some cases exclude every fields but biography, I used the match_none to keep it "simple" (one entry in the should per word) and exclude the artist from a search that is clearly an artwork.

like image 152
Julien TASSIN Avatar answered Nov 12 '22 23:11

Julien TASSIN


match_none is a lifesaver if you're constructing your DSL string dynamically.

Let's say I have a webservice that performs a search by surname in two queries.

The first to retrieve a list of GUIDs for the surnames. Which are then used in a filter in the second query to retrieve only those records containing matching GUIDs. For example:

  "filter": [
    {
      "bool": {
        "should": [
          {
            "match": {
              "fieldname": {
                "query": "be032b00-525d-11e3-9cf0-18cf5eb3e8c4"
              }
            }
          },
          {
            "match": {
              "fieldname": {
                "query": "49b2c32e-5j64-11e3-a6e2-0f0d3ab1e588"
              }
            }
          }
        ]
      }
    }
  ]

If there are no matching surnames from the first query, I can use match_none to quickly reflect that.

"filter": [
  {
    "match_none": {}
  }
]
like image 3
Kingsley Avatar answered Nov 12 '22 23:11

Kingsley


Kinda old, but I have another example. I have an interface that fires off queries based on some combination of options (checkbox values) and text input. There just so happens to be a combination of options, that when selected, I know will never match anything. I'm also using some helper functions to build my query - because even in javascript those queries are ugly and big, and I want to keep them far away from my pretty tsx react code. So, it is quite convenient to simply detect the options which result in a query which will never match anything and return a query with match_none. A rough sketch of the idea is below.

import React, { useState, useCallback } from "react";                            
                                                                                 
const bodyBuilder = (option: boolean) =>                                         
  option                                                                         
    ? {                                                                          
        query: { match_none: {} },                                               
      }                                                                          
    : {                                                                          
        query: {                                                                 
          match: {                                                               
            field: "something",                                                  
          },                                                                     
        },                                                                       
      };                                                                         
                                                                                 
function Component() {                                                           
  const [option, setOption] = useState(true);                                    
                                                                                 
  const endpoint = "http://esserver:9200/myindex/_search";                       
  const searchBody = bodyBuilder(option);                                        
                                                                                 
  const onClick = useCallback((e: any) => {                                      
    e.preventDefault();                                                          
    fetch(endpoint, { method: "POST", body: JSON.stringify(searchBody) })        
      .then(console.log);                                                        
  },[searchBody]);                                                                
                                                                                 
  return (                                                                       
    <form>                                                                       
      <input                                                                     
        type="checkbox"                                                          
        checked={option}                                                         
        onChange={() => setOption(!option)}                                      
      />                                                                         
      <input type="submit" onClick={onClick} />                                  
    </form>                                                                      
  );                                                                             
}                                                                                                                                                                                              
like image 2
Nathan Chappell Avatar answered Nov 12 '22 21:11

Nathan Chappell