Поиск по специальному символу с использованием ElasticSearch - PullRequest
1 голос
/ 04 апреля 2020

Я использую ElasticSearch в моем VB.NET проекте. Нормальный поиск работает нормально т.е. по любому слову. Но теперь, исходя из требований, я также хочу искать по специальному символу, например ?. Я использую ? как обычный поиск, но он работает неправильно.

Код:

client.CreateIndex(Function(d) d.Analysis(Function(z) z.Analyzers(Function(a) a.Add("nGram_analyzer", Get_nGram_analyzer()).
Add("whitespace_analyzer", Get_whitespace_analyzer()).
Add("autocmp", New Nest.CustomAnalyzer() With {.Tokenizer = "edgeNGram", .Filter = {"lowercase"}})).
Tokenizers(Function(t) t.Add("edgeNGram", New Nest.EdgeNGramTokenizer With {.MinGram = 1, .MaxGram = 20})).
TokenFilters(Function(t) t.Add("nGram_filter", Get_nGram_filter()))).
Index(Of view_Article).AddMapping(Of view_Article)(ArticleMapping)

Private Shared Function Get_nGram_filter() As NgramFilter

        Return New NgramFilter With {
            .MinGram = 1,
            .MaxGram = 20,
            .token_chars = New List(Of String) From {"letter", "digit", "punctuation", "symbol"}
        }
End Function

Private Shared Function Get_nGram_analyzer() As CustomAnalyzer
        Return New CustomAnalyzer() With {
            .Tokenizer = "whitespace",
            .Filter = New List(Of String)() From {"lowercase", "asciifolding", "nGram_filter"}
        }
End Function

Private Shared Function Get_whitespace_analyzer() As CustomAnalyzer
        Return New CustomAnalyzer() With {
            .Tokenizer = "whitespace",
            .Filter = New List(Of String)() From {"lowercase", "asciifolding"}
        }
End Function

Поисковый запрос:

"query": {
    "query_string": {
      "query": "\\?",
      "fields": [
        "title"
      ],
      "default_operator": "and",
      "analyze_wildcard": true
    }
  }

Примечание: Я хочу найти его во многих отношениях. т.е. ключевое слово, ключевое слово + специальный символ или просто специальный символ.

Ответы [ 2 ]

1 голос
/ 04 апреля 2020

Изменение моего ответа на основе обсуждения с @jeeten, также ответ, данный @Nishant, будет работать, но имеет следующие функциональные и нефункциональные проблемы:

Функциональная проблема:

  1. В поиске допускаются только ? и / специальные символы, при этом он позволяет выполнять поиск по всем пунктуациям.

Нефункциональные проблемы:

Это приведет к тому, что 3 поля будут проиндексированы в другом формате, что увеличит размер индекса на диске, а также увеличит нагрузку на память, поскольку Elasticsearch кэширует инвертированный индекс для лучшей производительности поиска.

Опять же, для поиска требуются все три поля для поиска, а поиск в других полях снова вызывает проблемы с производительностью.

токены дублируются в трех полях title field.

Мое решение

Чтобы удовлетворить вышеуказанные функциональные и нефункциональные требования, я использовал [pattern_capture][1] token-filter для индексации только ? и /, он также использует "preserve_original": true, для поддержки поиска типа foo?.

Я также индексирую 2 поля и ищу только в двух полях для повышения производительности.

Индекс def

{
    "settings": {
        "analysis": {
            "filter": {
                "splcharfilter": {
                    "type": "pattern_capture",
                    "preserve_original": true,
                    "patterns": [
                        "([?/])" --> extendable for future requirments.
                    ]
                }
            },
            "analyzer": {
                "splcharanalyzer": {
                    "tokenizer": "keyword",
                    "filter": [
                        "splcharfilter",
                        "lowercase"
                    ]
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "title": {
                "type": "text",
                "fields": {
                    "splchar": {
                        "type": "text",
                        "analyzer": "splcharanalyzer"
                    }
                }
            }
        }
    }
}

Поисковый запрос

{
  "query": {
    "query_string": {
      "query": "\\?", --> change this according to queries.
      "fields": ["title", "title.splchar"] --> noyte only 2 fields
    }
  }
}

Результат поиска

"hits": [
            {
                "_index": "pattern-capture",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.0341108,
                "_source": {
                    "title": "Are you ready to change the climate?"
                }
            },
            {
                "_index": "pattern-capture",
                "_type": "_doc",
                "_id": "4",
                "_score": 1.0341108,
                "_source": {
                    "title": "What are the effects of direct public transfers on social solidarity?"
                }
            }
        ]

PS: - Не упоминая все поисковые запросы и их вывод, чтобы сделать ответ коротким, но любой может проиндексировать и изменить поисковые запросы, и он работает как ожидалось .

0 голосов
/ 09 апреля 2020

Принимая следующее, например, из чата в качестве базы:

Some example titles: 

title: Climate: The case of Nigerian agriculture
title: Are you ready to change the climate?
title: A literature review with a particular focus on the school staff
title: What are the effects of direct public transfers on social solidarity?
title: Community-Led Practical and/or Social Support Interventions for Adults Living at Home.

If I search by only "?" then it should return the 2nd and 4th results.
If I search by "/" then it should return only last record.
Search by climate then 1st and 2nd results.
Search by climate? then 1st, 2nd, and 4th results.

Для решения потребуется создать анализаторы для следующих случаев:

  1. Для поиска особый персонаж. Я рассматриваю их как пунктуацию, например /, ? et c.
  2. Для поиска по ключевому слову и специальному символу. Например, climate?
  3. Для поиска по ключевому слову. например, climate

Для case 1 мы будем использовать pattern tokenizer , но вместо использования pattern для разделения мы будем использовать pattern для извлечения специальных символов в качестве токенов, и для этого мы устанавливаем "group": 0 при определении токенизатора. например, для текста xyz a/b pq? сгенерированные токены будут /, ?

Для case 2 мы создадим собственный анализатор с filter как lowercase (для создания case нечувствителен) и tokenizer как whitespace (для сохранения специальных символов с ключевыми словами). например, для текста How many? сгенерированные токены будут how, many?

Для case 3 мы будем использовать standard анализатор, который является анализатором по умолчанию.

Следующим шагом будет создание подполей для title. title будет иметь тип text и по умолчанию будет иметь standard анализатор. Это свойство отображения будет иметь два подполя withSplChar типа text и анализатор, созданный для case 2 (ci_whitespace), splChars типа text и анализатор, созданный для case 1 (splchar)

Давайте теперь посмотрим на вышесказанное в действии:

PUT test
{
  "settings": {
    "analysis": {
      "tokenizer": {
        "splchar": {
          "type": "pattern",
          "pattern": "\\p{Punct}",
          "group": 0
        }
      },
      "analyzer": {
        "splchar": {
          "tokenizer": "splchar"
        },
        "ci_whitespace": {
          "type": "custom",
          "filter": [
            "lowercase"
          ],
          "tokenizer": "whitespace"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "withSplChar": {
            "type": "text",
            "analyzer": "ci_whitespace"
          },
          "splChars": {
            "type": "text",
            "analyzer": "splchar"
          }
        }
      }
    }
  }
}

Давайте теперь индексируем документы, как в примере выше:

POST test/_bulk
{"index":{"_id":"1"}}
{"title":"Climate: The case of Nigerian agriculture"}
{"index":{"_id":"2"}}
{"title":"Are you ready to change the climate?"}
{"index":{"_id":"3"}}
{"title":"A literature review with a particular focus on the school staff"}
{"index":{"_id":"4"}}
{"title":"What are the effects of direct public transfers on social solidarity?"}
{"index":{"_id":"5"}}
{"title":"Community-Led Practical and/or Social Support Interventions for Adults Living at Home."}

Поиск ?

"hits" : [
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "2",
    "_score" : 0.8025915,
    "_source" : {
      "title" : "Are you ready to change the climate?"
    }
  },
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "4",
    "_score" : 0.8025915,
    "_source" : {
      "title" : "What are the effects of direct public transfers on social solidarity?"
    }
  }
]

Результат:

   "hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.8025915,
        "_source" : {
          "title" : "Are you ready to change the climate?"
        }
      },
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 0.8025915,
        "_source" : {
          "title" : "What are the effects of direct public transfers on social solidarity?"
        }
      }
    ]

Поиск climate

POST test/_search
{
  "query": {
    "query_string": {
      "query": "climate",
      "fields": ["title", "title.withSplChar", "title.splChars"]
    }
  }
}

Результат :

"hits" : [
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "1",
    "_score" : 1.0341107,
    "_source" : {
      "title" : "Climate: The case of Nigerian agriculture"
    }
  },
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "2",
    "_score" : 0.98455274,
    "_source" : {
      "title" : "Are you ready to change the climate?"
    }
  }
]

Поиск climate?

POST test/_search
{
  "query": {
    "query_string": {
      "query": "climate\\?",
      "fields": ["title", "title.withSplChar", "title.splChars"]
    }
  }
}

Результат:

"hits" : [
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "2",
    "_score" : 1.5366155,
    "_source" : {
      "title" : "Are you ready to change the climate?"
    }
  },
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "1",
    "_score" : 1.0341107,
    "_source" : {
      "title" : "Climate: The case of Nigerian agriculture"
    }
  },
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "4",
    "_score" : 0.8025915,
    "_source" : {
      "title" : "What are the effects of direct public transfers on social solidarity?"
    }
  }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...