【问题标题】:Elasticsearch and C# - query to find exact matches over stringsElasticsearch 和 C# - 查询以查找字符串的完全匹配
【发布时间】:2015-09-02 14:30:29
【问题描述】:

我需要一种在“字符串”和“整数”类型的两个或多个字段上使用纯精确匹配来搜索文档的方法。

我想避免标准查询,因为我不关心得分或最佳匹配,如果两个字段都匹配,则只关心是/否结果。

我知道我可以使用过滤器来做到这一点,但我只得到了使用 JSON 格式的示例查询。我想在 C# 环境中进行这样的搜索。

这是我的映射:

{
   "reviewer-test-index": {
      "aliases": {},
      "mappings": {
         "historyRecord": {
            "properties": {
               "groupName": {
                  "type": "string"
               },
               "groupNo": {
                  "type": "integer"
               },
               "instrType": {
                  "type": "integer"
               },
               "instrumentAddress": {
                  "type": "string"
               },
               "insturmentName": {
                  "type": "string"
               },
               "macAddr": {
                  "type": "string"
               },
               "uhhVersion": {
                  "type": "string"
               }
            }
         },         
      "settings": {
         "index": {
            "creation_date": "1434557536720",
            "number_of_shards": "1",
            "number_of_replicas": "0",
            "version": {
               "created": "1050299"
            },
            "uuid": "FfQADLGVQVOPV3913exKsw"
         }
      },
      "warmers": {}
   }
}

我也尝试进行 JSON 查询,但获得 0 次点击:

GET _search
{
  "query" :{
  "filtered": {
    "query": {
      "match_all": { }
    },
   "filter": {
      "bool" : {
            "must" : [
                {"term" : { "macAddr" : "000A8D810F5A" } },
                {"term" : { "insturmentName" : "Amin's furnace" } },
                {"term" : { "instrumentAddress" : "8D810F5A"}},
                {"term" : { "uhhVersion" :  "v2.5"}},
                {"term" : { "groupName" :  "Amin's Group"}},
                {"term" : { "groupNo" :  2}},
                {"term" : { "instrType" :  60}}
            ]
         }
    }
  }
  }
}

Response:

{
   "took": 3,
   "timed_out": false,
   "_shards": {
      "total": 4,
      "successful": 3,
      "failed": 0
   },
   "hits": {
      "total": 0,
      "max_score": null,
      "hits": []
   }
}

【问题讨论】:

    标签: c# .net database elasticsearch nest


    【解决方案1】:

    您可以将过滤后的查询与术语过滤器一起使用:

    {
      "filtered": {
        "query": {
          "match_all": { }
        },
        "filter": {
          "bool" : {
                "must" : [
                    {"term" : { "macaddress" : "your_mac" } },
                    {"term" : { "another_field" : 123 } }
                ]
             }
        }
      }
    }
    

    NEST 版本(将 dynamic 替换为您的响应模型):

    var res = esclient.Search<dynamic>(q => q
                .Query(fq => fq
                    .Filtered(fqq => fqq
                        .Query(qq => qq.MatchAll())
                        .Filter(ff => ff
                            .Bool(b => b
                                .Must(m1 => m1.Term("macaddress", "your_mac"))
                                .Must(m2 => m2.Term("another_field", 123))
                            )
                        )
                    )
                )
            );
    

    根据提供的映射和响应进行更新:

    首先需要注意以下几点:

    • 当我们需要索引和搜索关键字或ID时,我们使用term。在您的情况下,它是“macAddr”,但问题是您使用标准分析器对其进行索引(因此000A8D810F5A 将转换为000a8d810f5a),并使用term 搜索它(它将保留传递的数据==> @ 987654328@),那么它将永远不会匹配索引数据:000a8d810f5a。 您可以在搜索之前通过小写术语或使用match 查询来解决它。 case "instrumentAddress" & "uhhVersion" 可能相同(我不确定,因为我没有样本数据)。

    • 对于案例“insturmentName”、“groupName”,您正在使用标准分析器为短语编制索引。因此,像“Amin 的熔炉”这样的数据将被索引为两个术语 amin'sfurnace,并且它们都不匹配传递的术语 Amin's furnace。 在这种情况下,我们可以使用match 查询进行搜索(如果您需要更多选项,也可以使用query_string

    所以快速修复将如下所示:

    GET _search
    {
    "query" :{
      "filtered": {
         "query": {
            "match_all": { }
          },
         "filter": {
           "bool" : {
            "must" : [
                {"match" : { "macAddr" : "000A8D810F5A" } },
                {"match" : { "insturmentName" : "Amin's furnace" } },
                {"match" : { "instrumentAddress" : "8D810F5A"}},
                {"term" : { "uhhVersion" :  "v2.5"}},
                {"match" : { "groupName" :  "Amin's Group"}},
                {"term" : { "groupNo" :  2}},
                {"term" : { "instrType" :  60}}
              ]
            }
           }
          }
         }
       }
    

    如果您可以将“macAddr”、“instrumentAddress”的搜索词小写,那么您可以将其匹配查询替换为词查询以获得更好的性能。

    【讨论】:

    • 好的,谢谢,如果您提供 C# NEST 代码,我会接受答案
    • 好的,谢谢!如果我想对字符串进行多次匹配,比如说两个过滤规则 AND 在一起怎么办?这是我的主要问题:-)
    • 您的意思是将另一个字段与您的 macaddress 一起匹配?您可以更新问题,然后我可以更新答案以使其清楚。
    • 是的,就是这样......我已经更新了这个问题。谢谢!
    • 嗯。出于某种奇怪的原因,代码将所有文档返回给我,而不仅仅是一个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    相关资源
    最近更新 更多