什么match_none有用?

时间:2017-11-04 09:26:00

标签: elasticsearch

我查看了docs和其他引用,无法理解match_none查询在什么情况下有用?

我怀疑它可能在一些bool查询中很方便吗?它本身就很奇怪。

参考文献:

4 个答案:

答案 0 :(得分:2)

在评论中发帖太久了,抱歉垃圾邮件答案:/

我在一个过滤器中使用它,其中最小值应匹配以自己处理非相关单词,而不进行弹性搜索("非相关"单词取决于上下文)。

示例,查看艺术家索引和艺术品索引,并向用户呈现最相关的搜索结果如下:

"An artwork blue"

artwork不是在艺术家索引中搜索的相关单词(它会将很多噪音与传记,评论等相匹配,但是没有意义),除非用户正在寻找名为的艺术家"艺术品&#34 ;.

我对艺术家索引的过滤器(以某种更复杂的方式)看起来像这样:

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

由于它是动态构建的(动态最小值应该匹配)并且在某些情况下可以排除除传记之外的每个字段,我使用match_none来保持它简单" (每个单词应该输入一个条目)并将艺术家排除在显然是艺术品的搜索之外。

答案 1 :(得分:1)

金达老了,但我有另一个例子。我有一个界面,可以根据选项(复选框值)和文本输入的某种组合触发查询。碰巧是选项的组合,选择后我知道永远不会匹配任何选项。我还使用了一些辅助函数来构建查询-因为即使在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>                                                                      
  );                                                                             
}                                                                                                                                                                                              

答案 2 :(得分:1)

如果您正在动态构建 DSL 字符串,

ma​​tch_none 是一个救星。

假设我有一个在两个查询中按姓氏进行搜索的网络服务。

第一个检索姓氏的 GUID 列表。然后在第二个查询的过滤器中使用它们以仅检索包含匹配 GUID 的那些记录。例如:

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

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

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

答案 3 :(得分:0)

使用 match_none(和 match_all)的一个边缘情况是动态构建 search templates

如果使用 mustache,您的逻辑将输出无效的 JSON(JSON 与模板指令混合)。在某些情况下,您可以从列表生成查询子句。一种方法是在包含小胡子条件的列表中添加标记对象,stringify 结果 JSON,然后对字符串进行后处理(字符串替换)以删除小胡子文字周围的引号/逗号.这可能会给您留下一个尾随逗号。如果您只是在列表中添加最后一个 match_none,那么您的 JSON 将再次有效。 (这适用于“或”(应该)bool 查询,而不适用于 must。)

这是伪javascript中的一个例子:

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

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

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 为真(并且呈现来自最后一个可选子句的逗号,您将有一个最终的无操作查询以确保 JSON 是有效。