Постобработка Elasticsearch с использованием фонетики - PullRequest
0 голосов
/ 11 февраля 2019

Я играю с Elasticsearch для будущего внедрения в производственной среде.Моя проблема в том, что мне нужно использовать нечеткий поиск и фонетику для достижения моей цели, а именно:

  • Запрос с использованием нечеткого соответствия
GET _search
{
  "query": {
    "bool": {
      "should": [
        {
          "multi_match": {
            "type": "most_fields", 
            "query": "MUSIC: DOWNLOAD The Beatle$ – hey jode -FLAC-WEB- CDQ-2014",
            "fuzzy_transpositions": "true", 
            "fuzziness": "AUTO", 
            "fields": ["artist_name", "title_track"],
            "slop": 100,
            "max_expansions": 30
          }
        },
        {
          "multi_match": {
            "type": "cross_fields", 
            "query": "MUSIC: DOWNLOAD The Beatle$ – hey jode -FLAC-WEB- CDQ-2014",
            "fields": ["artist_name", "title_track"],
            "boost": 5, 
            "operator": "and",
            "max_expansions": 30
          }
        }]
}
}
}
  • Результатыдовольно хороши, даже если запутать строку, как в запросе:
{
  "took": 316,
  "timed_out": false,
  "_shards": {
    "total": 11,
    "successful": 11,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1169343,
    "max_score": 26.201363,
    "hits": [
      {
        "_index": "repmatch",
        "_type": "repertoire",
        "_id": "zVzFm2gB0djhmNXkB5y-",
        "_score": 26.201363,
        "_source": {
          "title_track": "HEY JUDE",
          "album_id": null,
          "artist_id": 38387,
          "artist_name": """"BEATLES, THE""""
        }
      },
      {
        "_index": "repmatch",
        "_type": "repertoire",
        "_id": "X1ETmmgB0djhmNXkARTQ",
        "_score": 26.201363,
        "_source": {
          "title_track": "HEY JUDE",
          "album_id": null,
          "artist_id": 21183,
          "artist_name": "THE  BEATLES"
        }
      },
      {
        "_index": "repmatch",
        "_type": "repertoire",
        "_id": "MF34m2gB0djhmNXkTvIn",
        "_score": 26.080318,
        "_source": {
          "title_track": "HEY JUDE",
          "album_id": 6135978,
          "artist_id": 40333,
          "artist_name": "BEATLES, THE"
        }
      },
...

  • Проблема начинается, когда у меня нет индексированного исполнителя и / или трека:
GET _search
{
  "query": {
    "bool": {
      "should": [
        {
          "multi_match": {
            "type": "most_fields", 
            "query": "justin bieber - sorry",
            "fuzzy_transpositions": "true", 
            "fuzziness": "AUTO", 
            "fields": ["artist_name", "title_track"],
            "slop": 100,
            "max_expansions": 30
          }
        },
        {
          "multi_match": {
            "type": "cross_fields", 
            "query": "justin bieber - sorry",
            "fields": ["artist_name", "title_track"],
            "boost": 5, 
            "operator": "and",
            "max_expansions": 30
          }
        }]
}
}
}
  • Результаты не возвращаются Джастину Биберу, поскольку он не проиндексирован
{
  "took": 121,
  "timed_out": false,
  "_shards": {
    "total": 11,
    "successful": 11,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 19730,
    "max_score": 24.51635,
    "hits": [
      {
        "_index": "repmatch",
        "_type": "repertoire",
        "_id": "-XfOn2gB0djhmNXkENiE",
        "_score": 24.51635,
        "_source": {
          "title_track": "JUSTIN",
          "album_id": 5897467,
          "artist_id": 117964,
          "artist_name": "JUSTIN"
        }
      },
      {
        "_index": "repmatch",
        "_type": "repertoire",
        "_id": "yXfOn2gB0djhmNXkCdjW",
        "_score": 24.42126,
        "_source": {
          "title_track": "JUSTIN",
          "album_id": null,
          "artist_id": 117964,
          "artist_name": "JUSTIN"
        }
      },
      {
        "_index": "repmatch",
        "_type": "repertoire",
        "_id": "iDxal2gB0djhmNXkY_ew",
        "_score": 23.26923,
        "_source": {
          "title_track": "JUSTIN BIEBER",
          "album_id": null,
          "artist_id": 10851,
          "artist_name": "SMASH MOUTH"
        }
      },
...

Цель состоит в том, чтобы узнать, проиндексированы ли исполнитель и трек.Мне нужны как можно более точные результаты, но я все еще использую нечеткость для покрытия орфографических ошибок.

Моя идея состоит в том, чтобы использовать плагин фонетики с метафоном для последующей обработки полученных документов и входной строки, и таким образом определить,сгенерированный метафон для документов присутствует на метафоне для входной строки.Я надеялся, что смогу предоставить один запрос, и Elasticsearch сможет вернуть всю эту информацию о том же наборе результатов или даже сказать мне, было ли найдено совпадение.

Я мог бы использовать только строку фонетики, вызывающую:

GET phonetic/_analyze
{
  "analyzer": "phonetic",
  "text": "The Beatles – Hello Goodbye"
} 

или

GET /phonetic/phonetic/_search
{
    "query": {
        "match": {
            "user.phonetic": {
                "query":"beatles"
            }
        }
    }
}

Это очень далеко от того, что мне нужно, так как я не мог использовать фонетику и нечеткий поиск в одном поле: \

Вот как были созданы фонетический анализатор и фильтр:

PUT /phonetic
{
  "settings": {
    "analysis": {
      "filter": {
        "dbl_metaphone": {
          "type":    "phonetic",
          "encoder": "double_metaphone"
        }
      },
      "analyzer": {
        "dbl_metaphone": {
          "tokenizer": "standard",
          "filter":    "dbl_metaphone"
        }
      }
    }
  }
}

PUT /phonetic/_mapping/phonetic
{
  "properties": {
    "user": {
      "type": "text",
      "fields": {
        "phonetic": {
          "type":     "text",
          "analyzer": "dbl_metaphone"
        }
      }
    }
  }
}

Я не нашел более подробного материала о плагине фонетики для Elasticsearch или, например, о том, как его использовать в сценариях (идея в этом случае заключается в публикации-обработать каждый документ и сгенерировать фонетику для каждого токена, а затем сравнить их с каждым словом в строке поиска).

Я мог бы написать внешнюю программу для получения и обработки результатов Elasticsearch, но теперь это было бы слишком неуклюжеУ меня было бы два API, один из которых вызывал другой (мне все еще нужно предоставлять результаты через API).

Подводя итог, мне нужно убедиться, что артист и трек проиндексированы, но в то же время мне нужно принять орфографические ошибки.

Большое спасибо заранее.

...