空字符串弹性搜索
Empty String elastic search
我正在使用 Elastic 6.5。
我需要使用我正在传递的条件之一包含一个空字符串搜索。
主键 = 1, 2, 3
subKey = "" 或 subKey = "A" 以及其他一些条件。
我一直无法获取子键为空的记录。
我试过使用 MUST_NOT EXISTS,但它没有获取有问题的记录。
所以下面应该 return 主键为 1、2 或 3 且子键为 '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")
)
)
));
关于如何解决这个问题有什么想法吗?非常感谢!
注意:我看到帖子说这可以通过过滤器来完成,使用 missing。但是正如您从查询中看到的那样,我需要查询来执行此操作,而不是过滤器。
我还尝试了以下而不是 MUST_NOT EXISTS
{
"term": { "subKey": { "value": "" }}
}
但不起作用。我在想我需要另一个分词器来让它工作。
好的,我设法通过使用多字段解决了这个问题。这就是我所做的。
将映射更改为:
.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 字符串。这看起来确实不理想。
如果有人有其他建议,那就太好了!
[更新] 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)))
我正在使用 Elastic 6.5。
我需要使用我正在传递的条件之一包含一个空字符串搜索。
主键 = 1, 2, 3
subKey = "" 或 subKey = "A" 以及其他一些条件。
我一直无法获取子键为空的记录。
我试过使用 MUST_NOT EXISTS,但它没有获取有问题的记录。
所以下面应该 return 主键为 1、2 或 3 且子键为 '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")
)
)
));
关于如何解决这个问题有什么想法吗?非常感谢!
注意:我看到帖子说这可以通过过滤器来完成,使用 missing。但是正如您从查询中看到的那样,我需要查询来执行此操作,而不是过滤器。
我还尝试了以下而不是 MUST_NOT EXISTS
{
"term": { "subKey": { "value": "" }}
}
但不起作用。我在想我需要另一个分词器来让它工作。
好的,我设法通过使用多字段解决了这个问题。这就是我所做的。
将映射更改为:
.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 字符串。这看起来确实不理想。
如果有人有其他建议,那就太好了!
[更新] 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)))