Elasticsearch запрос для поиска из разных полей не строго - PullRequest
1 голос
/ 19 февраля 2020

Я относительно новичок в работе с ArcticSearch и работаю с Elassearch в python. У меня были данные о людях в формате csv, которые я преобразовал в json и добавил в индекс эластичного поиска. Поля следующие:

'Last Name (Legal Name)', 
'First Name', 
'Middle Name', 
'Other Last Name', 
'Business Mailing Address City Name', 
'Business Mailing Address State Name',
'Business Practice Location Address City Name', 
'Business Practice Location Address State Name', 
'Authorized Official Last Name', 
'Authorized Official First Name', 
'Authorized Official Middle Name', 
'Authorized Official Title or Position'

То, что я хочу добавить в запрос, это что-то вроде «Name City». Например, «Клинтон Адамс Гамильтон», где Клинтон Адамс - это имя, а Гамильтон - город. В большинстве случаев я не буду уверен, какое имя или какое последнее, поэтому мне нужно будет сопоставить все поля.

То, что я использовал до сих пор, выглядит примерно так :

"query":{
                "query_string":{
                    "fields": ['Last Name (Legal Name)', 'First Name', 'Middle Name', 
                             'Other Last Name', 'Business Mailing Address City Name', 
                             'Business Mailing Address State Name',
                             'Business Practice Location Address City Name', 'Business Practice                            
                              Location Address State Name', 
                             'Authorized Official Last Name', 'Authorized Official First Name', 
                             'Authorized Official Middle Name', 
                             'Authorized Official Title or Position'],
                    "query": "(Clinton) AND (Adams) AND (Hamilton)",
                    }
                }

Следующий запрос работает нормально, если я ищу точное имя и город из базы данных, но если у меня есть орфографическая ошибка в имени или если в каком-то имени сокращено имя, оно не ' дайте ожидаемые результаты. Например, если запрос похож на «Клинтон А Гамильтон», он не будет соответствовать ни одному документу. Я не могу использовать оператор OR, так как есть несколько человек с похожими именами, поэтому важны все части запроса - имя / фамилия и город. Я бы хотел, чтобы запрос извлекал наиболее релевантную запись из индекса.

Я изо всех сил пытался объяснить ситуацию. В любом случае, не стесняйтесь спрашивать, если что-то не совсем понятно. Ценю ваши предложения. Спасибо.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

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

{
  'name', 
  'business_mailing': {
    'city',
    'state'
  },
  'business_practice_location': {
    'city',
    'state'
  }
}

Дело в том, что вам следует оптимизировать данные на основе запросов, которые вы хотите выполнить к ним.

С помощью В соответствии с приведенным выше отображением можно выполнить логический запрос (must), содержащий два запроса match, возможно, с параметром fuzzyness , настроенным для учета опечаток. , Например,

{
  'query': {
    'bool': {
      'must': [{
        'match': {
          'name': { 'query': 'Clinton Adams', 'fuzzyness': 'AUTO'
        }
      },{
        'match': {
          'business_mailing': { 'query': 'Hamilton', 'fuzzyness': 'AUTO'
        }
      }]
    }
  }
}

Другим решением может быть использование параметра отображения copy_to и определение нового запрашиваемого поля, которое включает в себя значения полей имени и полей города. Вот ссылка на документацию https://www.elastic.co/guide/en/elasticsearch/reference/7.5/copy-to.html

0 голосов
/ 19 февраля 2020

Прежде всего, вы должны попробовать запрос множественного соответствия, особенно тип cross_field, который подходит для вашего варианта использования. Документация здесь .

Он будет обрабатывать все искомые поля как одно смешанное поле.

Но если вы оставите оператор «И», запрос «Клинтон А Гамильтон» не будет соответствовать документу «Клинтон Адамс / Гамильтон». Я думаю, вы должны go для стандартного оператора ИЛИ. Это даст вам первый соответствующий документ в первой позиции. Точные совпадения первого и частичного после.

Если вы точно знаете, что многие ваши пользователи будут использовать миниатюрную форму для имени, вам следует подумать о создании специального анализатора для индексации миниатюрной формы.

Вот пример автономного индекса:

PUT diminutive
{
  "settings": {
    "analysis": {
      "filter": {
        "diminutive": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 3
        }
      }, 
      "analyzer": {
        "diminutive": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding",
            "diminutive"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "firstname": {
        "type": "text",
        "analyzer": "diminutive",
        "search_analyzer": "standard"
      }
    }
  }
}

Затем вы можете использовать миниатюрный анализатор в поле для 'First Name' (см. Документацию здесь ) и добавить подполе в запрос на множественное совпадение.

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

...