elasticsearch Elasticsearch Soundex匹配查询-嵌套,elasticsearch,logstash,c#-2.0,nest,soundex,elasticsearch,Logstash,C# 2.0,Nest,Soundex" /> elasticsearch Elasticsearch Soundex匹配查询-嵌套,elasticsearch,logstash,c#-2.0,nest,soundex,elasticsearch,Logstash,C# 2.0,Nest,Soundex" />

elasticsearch Elasticsearch Soundex匹配查询-嵌套

elasticsearch Elasticsearch Soundex匹配查询-嵌套,elasticsearch,logstash,c#-2.0,nest,soundex,elasticsearch,Logstash,C# 2.0,Nest,Soundex,有人能想一想为什么这可能不起作用吗?我基本上有两个字段,我使用soundex分析器对其进行索引,请参见下面的配置,但当我使用与索引中存储的名称类似的名称进行搜索时,它不起作用 anz.Custom("soundex_analyzer", dma => dma .Tokenizer("keyword") .Filters("lowercase", "icu_folding", "soundex_filter"))

有人能想一想为什么这可能不起作用吗?我基本上有两个字段,我使用soundex分析器对其进行索引,请参见下面的配置,但当我使用与索引中存储的名称类似的名称进行搜索时,它不起作用

anz.Custom("soundex_analyzer", dma => dma
                    .Tokenizer("keyword")
                    .Filters("lowercase", "icu_folding", "soundex_filter"));


tk.Phonetic("soundex_filter", ph => ph.Encoder(PhoneticEncoder.RefinedSoundex).Replace(false));

[String(Name = "surnameSoundex", Index = FieldIndexOption.Analyzed, Analyzer = "soundex_analyzer")]
public string SurnameSoundex { get; set; }

[String(Name = "forenameSoundex", Index = FieldIndexOption.Analyzed, Analyzer = "soundex_analyzer")]
public string ForenameSoundex { get; set; }


if (string.IsNullOrEmpty(oReq.person.ForenameSoundex) || oReq.person.ForenameSoundex.Length < 3)
  {
    _qc = _qd.Match(mt => mt.Field(fld => fld.SurnameSoundex).Query(oReq.person.SurnameSoundex));
    _AndQueries.Add(_qc);
    _qc = null;
  }
  else
     {
      //search on surname and combination of forename and surname
       _qc = _qd.Match(mt => mt.Field(fld => fld.SurnameSoundex).Query(oReq.person.SurnameSoundex))
                        || _qd.Match(mt => mt.Field(fld => fld.SurnameSoundex).Query(oReq.person.SurnameSoundex))
                        && _qd.Match(mt => mt.Field(fld => fld.ForenameSoundex).Query(oReq.person.ForenameSoundex));
       _AndQueries.Add(_qc);
       _qc = null;
       }
然后,我使用以下代码创建索引:

 Uri eSAddress = new Uri(ConfigurationManager.AppSettings["ElasticSearchUrl"]);
        _clientSettings = new ConnectionSettings(eSAddress)
            .MapDefaultTypeIndices(i => i.Add(typeof(Person), "people"));
        _client = new ElasticClient(_clientSettings);

        var oRequest = new IndexExistsRequest("people");
        var bIndexExists = _client.IndexExists(oRequest);

        if (bIndexExists.Exists == false)
        {
            var oIndexResponse = _client.CreateIndex("people", c => c
             .Settings(st => st
                .RefreshInterval(-1)
                .Translog((ts) => SetupTranslogSettings(ts))
                .NumberOfShards(1)
                .NumberOfReplicas(0)
                    .Analysis(an => an
                        .TokenFilters((tf) => SetUpFilters(tf))
                        .Analyzers((anz) => SetUpAnalyzers(anz)
                 )))
                .Mappings(mp => mp.Map<Person>(m => m
                .AutoMap()
                .AllField(al => al.Enabled(false)))));
我的分析器包括在下面-注意,我已更改为双变音标记过滤器:

 public static void AddSoundexAnalyzer(ref AnalyzersDescriptor anz)
    {
        anz.Custom("soundex_analyzer", dma => dma
                    .Tokenizer("keyword")
                    .Filters("soundex_filter"));
    }

 public static void AddSoundexFilter(ref TokenFiltersDescriptor tk)
    {
        tk.Phonetic("soundex_filter", ph => ph.Encoder(PhoneticEncoder.DoubleMetaphone).Replace(true));
    }
然后,我使用bool查询进行查询,其中的查询必须与至少一个查询匹配

  public SearchDescriptor<Person> FuzzySearch(PersonSearchRequest oReq)
    {
        var oPerson = oReq.person;
        var oSearchParams = oReq.searchParams;
        _s = new SearchDescriptor<Person>();
        _b = new BoolQueryDescriptor<Person>();
        _AndQueries = new List<QueryContainer>();
        _OrQueries = new List<QueryContainer>();

        GetNameSearchClauses(oReq, ref _OrQueries, ref _AndQueries);

        if (_OrQueries.Count > 0 || _AndQueries.Count > 0)
        {
            _b.Should(_OrQueries.ToArray());
            _b.Must(_AndQueries.ToArray());
            return _s.Query(qu => qu.Bool((z) => _b)).Sort(srt => srt.Descending(SortSpecialField.Score));
        }
        else
        {
            return null;
        }
    }
公共搜索描述符模糊搜索(PersonSearchRequest oReq)
{
var oPerson=oReq.人;
var oSearchParams=oReq.searchParams;
_s=新的搜索描述符();
_b=新的BoolQueryDescriptor();
_AndQueries=新列表();
_OrQueries=新列表();
GetNameSearchClaires(oReq、ref\u或查询、ref\u和查询);
如果(_或querys.Count>0 ||_和querys.Count>0)
{
_b、 应该(_或querys.ToArray());
_b、 必须(_和querys.ToArray());
返回_.Query(qu=>qu.Bool((z)=>u.b)).Sort(srt=>srt.Descending(SortSpecialField.Score));
}
其他的
{
返回null;
}
}
然后,我的forenameSoundex和NonsameSoundEx查询采用以下方法构造:

  public void GetNameSearchClauses(PersonSearchRequest oReq, ref List<QueryContainer> _OrQueries, ref List<QueryContainer> _AndQueries)
    {
        if (oReq.searchParams.useSoundex == true && oReq.person.surnameSoundex.Length > 3)//use different analyzers
        {
            if (!string.IsNullOrEmpty(oReq.person.surnameSoundex))
            {//check if clause is null

                //if no first name then just search on surname
                if (string.IsNullOrEmpty(oReq.person.forenameSoundex) || oReq.person.forenameSoundex.Length < 3)
                {
                    _qc = _qd.Match(mt => mt.Field(fld => fld.surnameSoundex).Query(oReq.person.surnameSoundex));
                    _AndQueries.Add(_qc);
                    _qc = null;
                }
                else
                {
                    //search on surname and combination of forename and surname
                    _qc = _qd.Match(mt => mt.Field(fld => fld.surnameSoundex).Query(oReq.person.surnameSoundex))
                        || _qd.Match(mt => mt.Field(fld => fld.surnameSoundex).Query(oReq.person.surnameSoundex))
                        && _qd.Match(mt => mt.Field(fld => fld.forenameSoundex).Query(oReq.person.forenameSoundex));
                    _AndQueries.Add(_qc);
                    _qc = null;
                }
            }
        }
public void getnamesearch子句(personsearch请求oReq、ref List\u或querys、ref List\u和querys)
{
如果(oReq.searchParams.useSoundex==true&&oReq.person.namesoundex.Length>3)//使用不同的分析器
{
如果(!string.IsNullOrEmpty(oReq.person.namesSoundex))
{//检查子句是否为null
//如果没有名字,只需搜索姓氏即可
if(string.IsNullOrEmpty(oReq.person.forenameSoundex)| | oReq.person.forenameSoundex.Length<3)
{
_qc=_qd.Match(mt=>mt.Field(fld=>fld.namesoundex.Query(oReq.person.namesoundex));
_andquerys.Add(_qc);
_qc=null;
}
其他的
{
//姓氏搜索及名姓组合
_qc=_qd.Match(mt=>mt.Field(fld=>fld.namestsoundex.Query(oReq.person.namestsoundex))
||_qd.Match(mt=>mt.Field(fld=>fld.namesoundex.Query(oReq.person.namesoundex))
&&_qd.Match(mt=>mt.Field(fld=>fld.forenameSoundex.Query(oReq.person.forenameSoundex));
_andquerys.Add(_qc);
_qc=null;
}
}
}

}问题在于,使用jdbc插件进行日志存储时,它会自动将列名小写。因此,在我的sql语句中,当我创建一个别名以直接映射到elasticsearch字段名时,它在通过logstash时被转换为小写

我的jdbc配置需要以下行:
lowercase\u column\u names=>false

问题在于,使用jdbc插件进行日志存储时,它会自动将列名小写。因此,在我的sql语句中,当我创建一个别名以直接映射到elasticsearch字段名时,它在通过logstash时被转换为小写

我的jdbc配置需要以下行:
lowercase\u column\u names=>false

不同之处在于,我从logstash导入elasticsearch索引的记录没有得到正确的分析或分析,但如果我通过api添加记录,soundex会正常工作。还不知道为什么。你能提供一个小的可复制的例子吗?上面的内容看起来像是应用程序不同部分的代码片段,这将使任何人都很难提供答案好的,我添加了更多的细节,不幸的是,解决方案中的代码非常分散,但我试图提供更简洁的细节。还需要注意的是,当我使用带有关键字标记器和小写标记过滤器的分析器搜索由logstash索引的记录时,它的工作原理让我相信只有在使用语音过滤器。如果使用下面概述的嵌套方法对相同的记录编制索引,则双变音查询将返回该记录,但不会返回通过logstash编制索引的记录_client.Index(oPerson,i=>i.Index(“people”).Type(“person”).Id(oPerson.Id).Refresh());不同之处在于,我从logstash导入elasticsearch索引的记录没有得到正确的分析,但如果我通过api添加记录,soundex就会正常工作。还不知道为什么。你能提供一个小的可复制的例子吗?上面的内容看起来像是应用程序不同部分的代码片段,这将使任何人都很难提供答案好的,我添加了更多的细节,不幸的是,解决方案中的代码非常分散,但我试图提供更简洁的细节。还需要注意的是,当我使用带有关键字标记器和小写标记过滤器的分析器搜索由logstash索引的记录时,它的工作原理让我相信只有在使用语音过滤器。如果使用下面概述的嵌套方法对相同的记录编制索引,则双变音查询将返回该记录,但不会返回通过logstash编制索引的记录_client.Index(oPerson,i=>i.Index(“people”).Type(“person”).Id(oPerson.Id).Refresh());
  public SearchDescriptor<Person> FuzzySearch(PersonSearchRequest oReq)
    {
        var oPerson = oReq.person;
        var oSearchParams = oReq.searchParams;
        _s = new SearchDescriptor<Person>();
        _b = new BoolQueryDescriptor<Person>();
        _AndQueries = new List<QueryContainer>();
        _OrQueries = new List<QueryContainer>();

        GetNameSearchClauses(oReq, ref _OrQueries, ref _AndQueries);

        if (_OrQueries.Count > 0 || _AndQueries.Count > 0)
        {
            _b.Should(_OrQueries.ToArray());
            _b.Must(_AndQueries.ToArray());
            return _s.Query(qu => qu.Bool((z) => _b)).Sort(srt => srt.Descending(SortSpecialField.Score));
        }
        else
        {
            return null;
        }
    }
  public void GetNameSearchClauses(PersonSearchRequest oReq, ref List<QueryContainer> _OrQueries, ref List<QueryContainer> _AndQueries)
    {
        if (oReq.searchParams.useSoundex == true && oReq.person.surnameSoundex.Length > 3)//use different analyzers
        {
            if (!string.IsNullOrEmpty(oReq.person.surnameSoundex))
            {//check if clause is null

                //if no first name then just search on surname
                if (string.IsNullOrEmpty(oReq.person.forenameSoundex) || oReq.person.forenameSoundex.Length < 3)
                {
                    _qc = _qd.Match(mt => mt.Field(fld => fld.surnameSoundex).Query(oReq.person.surnameSoundex));
                    _AndQueries.Add(_qc);
                    _qc = null;
                }
                else
                {
                    //search on surname and combination of forename and surname
                    _qc = _qd.Match(mt => mt.Field(fld => fld.surnameSoundex).Query(oReq.person.surnameSoundex))
                        || _qd.Match(mt => mt.Field(fld => fld.surnameSoundex).Query(oReq.person.surnameSoundex))
                        && _qd.Match(mt => mt.Field(fld => fld.forenameSoundex).Query(oReq.person.forenameSoundex));
                    _AndQueries.Add(_qc);
                    _qc = null;
                }
            }
        }