空字符串弹性搜索

时间:2018-11-20 16:48:58

标签: elasticsearch nest

我正在使用Elastic 6.5。

我需要使用我通过的条件之一包括空字符串搜索。

primaryKey = 1,2,3

subKey =“”或subKey =“ A”以及许多其他条件。

我一直无法获得具有空subKey的记录。

我尝试使用MUST_NOT EXISTS,但是它没有获取相关记录。

因此,下面应返回主键为1、2或3且subKey为'A'或空字符串的所有记录。按提供的日期过滤。我得到了所有记录,但subKey为空的记录除外。

所以我尝试了这个:

{
  "size": 200, "from": 0,
  "query": {
    "bool": {
      "must": [{
                "bool": {
                  "should": [{ "terms": {"primaryKey": [1,2,3] }}]
                }
              },
              {
                "bool": {
                  "should": [ 
                              {"match": {"subKey": "A"}}, 
                              {
                                "bool" : {
                                  "must_not": [{ "exists": { "field": "subKey"} }]
                                }
                              }
                            ]
                }
              }],
      "filter": [{"range": {"startdate": {"lte": "2018-11-01"}}}]
    }
  }
}

子项字段是特殊的..实际是由LETTER搜索的。但我认为这不会产生任何影响..但这是我为该索引所使用的NEST编码。

new CreateIndexDescriptor("SpecialIndex").Settings(s => s
                .Analysis(a => a
                        .Analyzers(aa => aa
                            .Custom("subKey_analyzer", ma => ma
                                .Tokenizer("subKey_tokenizer")
                                .Filters("lowercase")
                            )
                        )
                        .Tokenizers(ta => ta
                            .NGram("subKey_tokenizer", t => t
                                .MinGram(1)
                                .MaxGram(1)
                                .TokenChars(new TokenChar[] { TokenChar.Letter, TokenChar.Whitespace })
                            )
                        )
                    )
                )
                .Mappings(ms => ms
                    .Map<SpecialIndex>(m => m
                        .Properties(p => p
                            .Text(s => s
                                .Name(x => x.subKey)
                                .Analyzer("subKey_analyzer")
                            )
                        )
                    ));

有关如何解决此问题的任何想法?非常感谢你!

注意:我见过一些帖子说可以使用过滤器来完成此操作,而不会使用。但是从查询中可以看到,我需要查询来执行此操作,而不是过滤器。

我还尝试了以下方法,而不是必须存在的方法

{
    "term": { "subKey": { "value": "" }}
}

但不起作用。我在想我需要另一个令牌生成器才能使它正常工作。

1 个答案:

答案 0 :(得分:0)

好的,我设法通过使用多字段来解决此问题。这就是我所做的。

将映射更改为此:

                  .Mappings(ms => ms
                    .Map<SpecialIndex>(m => m
                        .Properties(p => p
                            .Text(s => s
                                .Name(x => x.subKey)
                                .Fields(ff => ff
                                    .Text(tt => tt
                                        .Name("subKey")
                                        .Analyzer("subKey_analyzer")
                                    )
                                    .Keyword(k => k
                                        .Name("keyword")
                                        .IgnoreAbove(5)
                                    )
                                )
                            )
                        )
                    ));

然后我将查询BOOL件更改为此:

            "bool": {
                "should": [{
                    "match": {
                        "subKey.subKey": {
                            "query": "A"
                        }
                    }
                },
                {
                    "term": {
                        "subKey.keyword": {
                            "value": ""
                        }
                    }
                }]
            }

我真正不喜欢的是,我认为Elastic正在创建一个附加字段,只是为了查找同一字段的EMPTY字符串。这似乎并不理想。

任何人都有另一个很棒的建议!

[UPDATE] NEST实现需要使用SUFFIX来访问多字段。

.Bool(bb => bb
   .Should(bbs => bbs
      .Match(m => m.Field(f => f.subKey.Suffix("subKey")).Query(search.subKey)),
      bbs => bbs
      .Term(t => t.Verbatim().Field(f => f.subKey.Suffix("keyword")).Value(string.Empty)))