Добавление новых документов в эластичный поиск с отображением черезasticsearch.index, структура тела - PullRequest
1 голос
/ 11 октября 2019

Я создаю блогоподобное приложение с флягой (на основе мегаторума Мигеля Гринберга) и пытаюсь настроить индексацию ES, которая бы поддерживала функцию автозаполнения. Я борюсь с правильной настройкой индексации.

Я начал с (работающего) простого механизма индексации:

from flask import current_app

def add_to_index(index, model):
    if not current_app.elasticsearch:
        return
    payload = {}
    for field in model.__searchable__:
        payload[field] = getattr(model, field)
    current_app.elasticsearch.index(index=index, id=model.id, body=payload)

, и после некоторой забавы с Google я обнаружил, что мое тело может что-то выглядетьвот так (возможно, с меньшим количеством анализаторов, но я справляюсь точно так, как я где-то нашел, где автор утверждает, что это работает):

{
 "settings": {
"index": {
  "analysis": {
    "filter": {},
    "analyzer": {
      "keyword_analyzer": {
        "filter": [
          "lowercase",
          "asciifolding",
          "trim"
        ],
        "char_filter": [],
        "type": "custom",
        "tokenizer": "keyword"
      },
      "edge_ngram_analyzer": {
        "filter": [
          "lowercase"
        ],
        "tokenizer": "edge_ngram_tokenizer"
      },
      "edge_ngram_search_analyzer": {
        "tokenizer": "lowercase"
      }
    },
    "tokenizer": {
      "edge_ngram_tokenizer": {
        "type": "edge_ngram",
        "min_gram": 2,
        "max_gram": 5,
        "token_chars": [
          "letter"
        ]
      }
    }
  }
}
 },
"mappings": {
field: {
  "properties": {
    "name": {
      "type": "text",
      "fields": {
        "keywordstring": {
          "type": "text",
          "analyzer": "keyword_analyzer"
        },
        "edgengram": {
          "type": "text",
          "analyzer": "edge_ngram_analyzer",
          "search_analyzer": "edge_ngram_search_analyzer"
        },
        "completion": {
          "type": "completion"
        }
      },
      "analyzer": "standard"
    }
     }
   }
 }
}

Я понял, что могу изменить оригинальный механизм, например:

    for field in model.__searchable__:
    temp = getattr(model, field)
    fields[field] = {"properties": {
      "type": "text",
      "fields": {
        "keywordstring": {
          "type": "text",
          "analyzer": "keyword_analyzer"
        },
        "edgengram": {
          "type": "text",
          "analyzer": "edge_ngram_analyzer",
          "search_analyzer": "edge_ngram_search_analyzer"
        },
        "completion": {
          "type": "completion"
        }
      },
      "analyzer": "standard"
    }}
payload = {
    "settings": {
        "index": {
          "analysis": {
            "filter": {},
            "analyzer": {
              "keyword_analyzer": {
                "filter": [
                  "lowercase",
                  "asciifolding",
                  "trim"
                ],
                "char_filter": [],
                "type": "custom",
                "tokenizer": "keyword"
              },
              "edge_ngram_analyzer": {
                "filter": [
                  "lowercase"
                ],
                "tokenizer": "edge_ngram_tokenizer"
              },
              "edge_ngram_search_analyzer": {
                "tokenizer": "lowercase"
              }
            },
            "tokenizer": {
              "edge_ngram_tokenizer": {
                "type": "edge_ngram",
                "min_gram": 2,
                "max_gram": 5,
                "token_chars": [
                  "letter"
                ]
              }
            }
          }
        }
    },
    "mappings": fields
}

но вот где я потерялся. Куда я помещаю фактический контент (temp = getattr (модель, поле)) в этот документ, чтобы все это работало? Я не смог найти ни одного примера или соответствующей части документации, которая охватывала бы обновление индекса с немного более сложными сопоставлениями и так далее, это даже правильно / выполнимо? Каждое руководство, которое я вижу, охватывает массовую индексацию и каким-то образом мне не удается установить соединение.

1 Ответ

0 голосов
/ 11 октября 2019

Я думаю, вы немного запутались, позвольте мне попытаться объяснить. Вам нужно добавить один эластичный документ с:

current_app.elasticsearch.index (индекс = индекс, id = model.id, тело = полезная нагрузка)

, которыйиспользует метод index (), определенный в libasticastic-py lib. Проверьте пример здесь: https://elasticsearch -py.readthedocs.io / en / master / index.html # example-using тело должно быть вашимдокумент простой диктовки, как показано в примере из документа.

То, что вы устанавливаете, это настройки индекса, которые отличаются. Возьмите аналогию с базой данных, вы установите схему таблицы внутри документа.

Чтобы установить настройки, если вы хотите установить данные настройки, вам нужно использовать put_settings, как определено здесь: https://elasticsearch -py.readthedocs.io / en / master / api.html? Highlight= settings #asticsearch.client.ClusterClient.put_settings

Надеюсь, это поможет вам.

...