elasticsearch match_none的用途是什么?

bwntbbo3  于 2022-12-11  发布在  ElasticSearch
关注(0)|答案(5)|浏览(248)

我浏览了文档和其他参考资料,不明白match_none查询在什么情况下有用?
我怀疑它在一些布尔查询中可能很方便??就其本身而言,它似乎很奇怪。
参考文献:

0h4hbjxa

0h4hbjxa1#

太长了,无法在评论中发布,很抱歉垃圾邮件的答案:/
我用它在一个过滤器与最小应匹配处理非相关的话我自己,没有ElasticSearch(“非相关”的话取决于上下文)。
例如,在艺术家索引AND艺术作品索引中查找,并将最相关的搜索呈现给用户,如下所示:
"An artwork blue"
artwork不是用于在艺术家索引中搜索的相关词(它将与传记、评论等匹配很多噪声,但是是无意义的),除非用户正在寻找名为“Artwork”的艺术家。
我的艺术家索引过滤器看起来(在某种程度上更复杂的方式)像这样:

{
    "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%"
        }
    }
}

由于它是动态构建的(具有动态的最小should匹配),并且在某些情况下可以排除除biography之外的所有字段,因此我使用match_none来保持它的“简单”(每个单词在should中有一个条目),并将艺术家从明显是艺术品的搜索中排除。

dphi5xsq

dphi5xsq2#

如果动态地构造DSL字符串,match_none是一个救星。
假设我有一个Web服务,它在两个查询中按姓氏执行搜索。
首先检索姓氏的GUID列表。然后在第二个查询的筛选器中使用这些GUID,以便仅检索包含匹配GUID的记录。例如:

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

如果第一个查询中没有匹配的姓氏,我可以使用match_none快速反映出来。

"filter": [
  {
    "match_none": {}
  }
]
6mzjoqzu

6mzjoqzu3#

有点老,但我有另一个例子。我有一个接口,它基于一些选项的组合发出查询(复选框值)和文本输入。这里正好有一个选项组合,当我选择它时,我知道它永远不会匹配任何内容。我还使用了一些帮助函数来构建我的查询--因为即使在javascript中,这些查询也是丑陋和庞大的,我想让它们远离我漂亮的tsx react代码。因此,简单地检测导致查询永远不匹配的选项并返回match_none的查询是非常方便的。下面是这个想法的草图。

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>                                                                      
  );                                                                             
}
vm0i2vca

vm0i2vca4#

使用match_none(和match_all)的一个边缘情况是动态构建search templates
如果使用mustache,则逻辑将输出无效的JSON(JSON与模板指令混合)。在某些情况下,您可以从列表中生成查询子句。一种方法是在包含mustache条件的列表中添加标记对象,stringify生成JSON,然后进行后处理,(string-replace)字符串以删除mustache文字前后的引号/逗号。这可能会给您留下一个尾随逗号。如果您只是在列表中添加最后一个match_none,那么您的JSON将再次有效。(这将适用于'or'(should)布尔查询,而不是must。)
下面是一个使用伪javascript编写的示例:

const should_queries = [
{
condition: "mycondition",
query: { match: { foo: "{{ query }}" }}
},
{
condition: "mycondition",
query: { term: { bar: "{{ query }}" }}
}
];

//在这里您可以将should查询Map到

const processed_queries = [
"{{#mycondition}}",
{ match: { foo: "{{ query }}" }},
"{{/mycondition}}",
"{{#mycondition}}",
{ term: { bar: "{{ query }}" }},
"{{/mycondition}}"
]

现在,您可以呈现这个并去掉mustache指令周围的引号/逗号,但这样会在字符串中留下一个尾随逗号。JSON在结束数组括号之前会有一个无效的逗号(即{term: {bar: "{{query}}}},])。
要处理这个问题,可以在字符串化之前将一个match_none添加到处理过的列表中。

processed_queries.push({match_none:{}});

列表现在如下所示:

[
"{{#mycondition}}",
{ match: { foo: "{{ query }}" }},
"{{/mycondition}}",
"{{#mycondition}}",
{ term: { bar: "{{ query }}" }},
"{{/mycondition}}",
{ match_none: {}}
]

当它呈现为字符串时,即使mycondition为true(并且呈现了最后一个可选子句中的逗号),您也将有一个最终的no-op查询来确保JSON有效。

euoag5mw

euoag5mw5#

我给予你们举个简单的例子。我在一个项目中做了这个。
假设您不想将某些记录包括在结果中,除非用户有权访问这些记录。您可能有一个名为“OnlyForAdmin”的字段,其值为true或false。现在,当非管理员用户执行搜索时,您可以排除OnlyForAdmin=true的记录。

相关问题