Поиск пустой строки - PullRequest
       14

Поиск пустой строки

0 голосов
/ 20 ноября 2018

Я использую Elastic 6.5.

Мне нужно включить поиск пустой строки с одним из критериев, которые я прохожу.

primaryKey = 1, 2, 3

subKey = "" или subKey = "A" вместе со множеством других критериев.

Мне не удалось получить запись с пустым subKey.

Я пытался использовать MUST_NOT EXISTS, но он не извлекает соответствующую запись.

Поэтому ниже должны возвращаться все записи, у которых primarykey равен 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"}}}]
    }
  }
}

Поле подключа является специальным ..., где оно на самом деле ищется ПИСЬМО.Но я не думаю, что это что-то повлияет ... но вот код 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")
                            )
                        )
                    ));

Есть идеи, как решить эту проблему?Большое спасибо!

ПРИМЕЧАНИЕ: я видел сообщения о том, что это можно сделать с помощью фильтра, используя отсутствующие.Но как вы можете видеть из запроса, мне нужен Query для этого, а не фильтр.

Я также попробовал следующее, а не MUST_NOT EXISTS

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

, но нене работаетЯ думаю, мне нужен еще один токенизатор, чтобы это заработало.

1 Ответ

0 голосов
/ 20 ноября 2018

Хорошо, мне удалось это исправить, используя Multi-поля.Это то, что я сделал.

Изменил сопоставления следующим образом:

                  .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 создает дополнительное поле, чтобы найти пустые строки того же поля.Это действительно не кажется идеальным.

У кого-то есть еще одно предложение, которое было бы замечательно!

[ОБНОВЛЕНИЕ] В реализации 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)))
...