Elasticsearch和C# - 查询以查找字符串的完全匹配

时间:2015-06-17 11:25:22

标签: c# .net database elasticsearch nest

我需要一种方法来搜索文档,使用两个或多个字段的简单完全匹配,类型为" string"和"整数"。

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

我知道我可以使用过滤器来完成它,但我只使用JSON格式进行了示例查询。我想在C#环境中进行搜索。

这是我的映射:

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": []
   }
}

我还试图制作一个JSON查询,但我得到了0次点击:

using System;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace ChartTest
{
    public partial class Form1 : Form
    {
        public Form1( )
        {
            InitializeComponent( );

            var series = new Series( )
            {
                ChartType = SeriesChartType.Area,
                MarkerStyle = MarkerStyle.None,
                XValueType = ChartValueType.DateTime,
                YAxisType = AxisType.Primary,
            };

            AddLine( DateTime.Parse( "17/6/2015" ), series );
            AddLine( DateTime.Parse( "18/6/2015" ), series );
            AddLine( DateTime.Parse( "19/6/2015" ), series );
            AddLine( DateTime.Parse( "20/6/2015" ), series );
            AddLine( DateTime.Parse( "21/6/2015" ), series );

            chart1.Series.Add( series );
        }

        private static void AddLine( DateTime dateTime, Series series )
        {
            var endTime = dateTime.AddMinutes( 2 );
            series.Points.AddXY( dateTime, 0 );
            series.Points.AddXY( dateTime, 1 );
            series.Points.AddXY( endTime, 1 );
            series.Points.AddXY( endTime, 0 );
        }
    }
}

1 个答案:

答案 0 :(得分:2)

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

{
  "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))
                        )
                    )
                )
            )
        );

根据提供的映射更新&amp;响应:

首先需要注意的是:

  • 当我们需要索引&amp;时,我们会使用term搜索关键字或ID。在你的情况下,它是“macAddr”,但问题是你使用标准分析器对其进行索引(因此000A8D810F5A将转换为000a8d810f5a),并使用term进行搜索(这将保留传递的数据)因为它==&gt; 000A8D810F5A),它永远不会匹配索引数据:000a8d810f5a。 您可以在搜索前使用小写字母或使用match查询来解决该问题。案例“instrumentAddress”&amp; “uhhVersion”(我不确定,因为我没有样本数据)。

  • 对于案例“insturmentName”,“groupName”,您使用标准分析器索引词组。因此,像“Amin's炉”这样的数据将被编入两个术语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”小写搜索词,那么你可以将其匹配查询替换为术语查询以获得更好的性能。