elasticsearch,C#,Json,elasticsearch" /> elasticsearch,C#,Json,elasticsearch" />

C# ElasticSearch将多重匹配与Must相结合

C# ElasticSearch将多重匹配与Must相结合,c#,json,elasticsearch,C#,Json,elasticsearch,我有一个对象模型: string Name; // name of the person int Age; // age of the person string CreatedBy; // operator who created person 我的查询听起来是这样的:所有年龄>40且CreatedBy==“callum”且名称包含“ll”的文档。 CreatedBy是一个必要的控制范围 年龄也是必要的(但不是安全问题) Name是它可能变得模糊的地方,因为这是用户正在查询的内容。类似

我有一个对象模型:

string Name; // name of the person
int    Age; // age of the person
string CreatedBy; // operator who created person
我的查询听起来是这样的:
所有年龄>40且CreatedBy==“callum”且名称包含“ll”的文档。

CreatedBy
是一个必要的控制范围

年龄
也是必要的(但不是安全问题)

Name
是它可能变得模糊的地方,因为这是用户正在查询的内容。类似于
排序
包含

以下查询适用于前两部分:

"query": {
     "bool": {
         "must": [
            {
                "range": {
                   "age": {
                      "gt": 40
                   }
                }
            },
            {
                "match": {
                   "createdBy": "Callum"
                }   
            }
         ]
     }
   }
我试着添加一个
多重匹配
,因为最终它可能是一个跨
名称
地址
和其他信息位的搜索。我不知道该把它放在哪里


在我的示例中,嵌套查询将非常有用。所以首先过滤掉所有不相关的用户,然后过滤掉不相关的年龄。然后对相关字段进行模糊匹配。

基本上,您可以将查询分为两个块:

"query": {
         "filter":{
            "bool":
            {
                "must":[
                    {
                        "range": {
                           "age": {
                              "gt": 40
                           }
                        }
                    }
                ]
            }
          },
         "query":{
            "bool": {
                "must": [
                    {
                      "multi_match" : {
                        "query":    "ll", 
                        "fields": [ "createdBy", "Address","Name" ] ,
                        "fuzziness":2
                      }
                    }             
                ]
            }
          }
       }
您可以做的是在
filter
中使用条件来
filter
内容,然后使用过滤后的数据应用您的
多匹配
查询。我在
过滤器
中包含年龄的主要原因是,您不需要执行任何类型的自由文本搜索,只需使用静态值进行检查,您可以在
过滤器
必须
块中包含更多条件

您还可以阅读本文,这可能会给您一些概述


希望有帮助

因此,这个问题的答案并不简单

首先,您需要为创建一个分析器

因此,在.NET客户端中,它看起来像:

this.elasticClient.CreateIndex("customer", p => p
    .Settings(s => s
        .Analysis(a => a
            .TokenFilters(t => t
                .NGram("bigrams_filter", ng => ng
                    .MaxGram(2)
                    .MinGram(2)))
        .Analyzers(al => al
            .Custom("bigrams", l => l
                .Tokenizer("standard")
                .Filters("lowercase", "bigrams_filter"))))));

this.elasticClient.Map<Person>(m => m
    .Properties(props => props
    .String(s => s
        .Name(p => p.Name)
        .Index(FieldIndexOption.Analyzed)
        .Analyzer("bigrams"))
    .String(s => s
        .Name(p => p.CreatedBy)
        .NotAnalyzed())
    .Number(n => n
        .Name(p => p.Age))));
这里,我们有一个过滤查询。因此,查询始终是第一个运行的(还没有找到文档引用,但我已经阅读了),这将是部分术语匹配。然后,我们只需过滤——这是在查询之后完成的——就可以得到我们需要的结果子集


因为
ngrams
分析仪仅设置在
name
上,这是唯一一个部分匹配的列。因此,
CreatedBy
不会,因此我们对结果进行了安全保护。

我认为您错过了这样一个事实,
multi\u match
应该搜索包含
ll
的字符串。那么,它解决了您的问题了吗?你可以在这个链接中看到更多关于
multi_match
的信息不,它没有,但我离你更近了,我使用了你关于拆分为两个块的提示,查看了filter and query
wildcard
让我更近了,我不知道如何在多个字段上执行该操作您想在键入类似内容时进行搜索吗?有一个问题,我认为没有任何
匹配
过滤器!它只是查询,不能在筛选器上下文中使用。。。您可以使用
term
filter。顺便说一句,这很有效,需要测试和澄清。这是针对2.x版的,而且
查询始终是第一个运行的(找不到文档,但我已经读过了)
正好相反,它将首先过滤掉文档,然后对其应用查询。。如果elastic首先对1000k文档执行查询,然后应用
过滤器
,那么使用
过滤器
将没有任何好处,但是在2.0.0-beta1中<代码>已筛选的已弃用!所以你不能使用弹性2.x!这很奇怪,因为即使在文档中,也提到可以在
过滤器中使用
match
match
查询是高级全文查询!
GET customer/_search
{
    "query": {
        "filtered": {
           "query": {
            "multi_match": {
               "query": "ll",
               "fields": ["name"]
            }
           },
           "filter": {
               "bool": {
                       "must": [
                          {
                         "range": {
                            "age": {
                               "gt": 40
                            }
                         }
                      },
                      {
                         "match": {
                            "createdBy": "Callum"
                         }
                      }
                   ]
               }
           }
        }
    }
}