Есть ли какое-либо решение для поиска точного слова и содержащего слова как вasticsearch - PullRequest
0 голосов
/ 17 марта 2020
index: process.env.elasticSearchIndexName,
      body: {
        query: {
          bool: {
            must: [
              {
                match_phrase: {
                  title: `${searchKey}`,
                },
              },
            ],
          },
        },
      },
      from: (page || constants.pager.page),
      size: (limit || constants.pager.limit),

Я использую вышеуказанный метод, но проблема в том, что он ищет только совпадающие слова во всем тексте. он не может искать содержащие слова ... например, если title = "sweatshirt", чем, если я наберу слово "shirt", он должен получить результат, но в настоящее время не получил результат, используя вышеуказанный метод

1 Ответ

1 голос
/ 17 марта 2020

Стандартный анализатор (анализатор по умолчанию, если не указан) разбивает текст в токенах. Для предложения «это тест» генерируются токены, которые [this, is, a, test] Запрос Match_pharse разбивает текст в токенах, используя тот же анализатор, что и анализатор индексации, и возвращает документы, которые 1. содержат все токены 2. токены появляются в том же порядке.

Так как ваш текст - толстовка, в инвертированном индексе есть один токен для этой толстовки, который не будет соответствовать ни поту, ни рубашке

NGram tokenizer

Сначала токенайзер ngram разбивает текст на слова всякий раз, когда встречает один из указанных символов, а затем выдает N-граммы каждого слова указанной длины

Отображение

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 3,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "text":{
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

Запрос:

{
  "query": {
    "match": {
      "text": "shirt"
    }
  }
}

Если вы запустите запрос _analyze

GET my_index/_analyze
{
  "text": ["sweatshirt"],
  "analyzer": "my_analyzer"
}

, вы увидите, что токен ниже генерируется для текста толстовки , Размер токенов можно настроить с помощью min_gram и max_gram

{
  "tokens" : [
    {
      "token" : "swe",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "wea",
      "start_offset" : 1,
      "end_offset" : 4,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "eat",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "ats",
      "start_offset" : 3,
      "end_offset" : 6,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "tsh",
      "start_offset" : 4,
      "end_offset" : 7,
      "type" : "word",
      "position" : 4
    },
    {
      "token" : "shi",
      "start_offset" : 5,
      "end_offset" : 8,
      "type" : "word",
      "position" : 5
    },
    {
      "token" : "hir",
      "start_offset" : 6,
      "end_offset" : 9,
      "type" : "word",
      "position" : 6
    },
    {
      "token" : "irt",
      "start_offset" : 7,
      "end_offset" : 10,
      "type" : "word",
      "position" : 7
    }
  ]
}

Предупреждение: Ngrams увеличивают размер инвертированного индекса, поэтому используйте с соответствующими значениями min_gram и max_gram

Другой вариант - использовать подстановочный знак запрос. Для подстановочного знака все документы должны быть отсканированы, чтобы проверить, соответствует ли текст шаблону. У них низкая производительность. При использовании поиска по шаблону в полях not_analyzed, если вы хотите включить пробелы ex text.keyword

{
  "query": {
    "wildcard": {
      "text": {
        "value": "*shirt*"
      }
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...