Каков наилучший способ обработки нескольких IndexReaders и IndexSearchers? - PullRequest
0 голосов
/ 05 февраля 2020

В моем приложении есть функция приема zip-файлов. Каждый zip-файл будет загружен в соответствии с указанным c UserProject. Пользовательский проект может иметь несколько zip-файлов, импортированных в соответствии с этим. Каждый из этих импортированных файлов будет сохранен в Azure Blob с путем как: {ContainerName} / {UserId} / {ProjectId} / {Imported.zip}.

Я хочу извлечь файлы в zip и индексировать содержимое файла. Я думал о том, чтобы сохранить индексированные файлы по тому же пути, что и zip-файл, поскольку нет необходимости искать среди zip-файлов, принадлежащих различным проектам. Это также поможет мне в удалении индексов при удалении проекта. Структура файла в хранилище BLOB-объектов azure будет выглядеть следующим образом:

Container/
├── UserId1/
│   ├── Project1/
|       ├── ImportedFile1.zip
|       ├── ImportedFile2.zip
|       ├── segments.gen
|       ├── segments_N
|       ├── _1.si
│   ├── Project2/
|       ├── ImportedFile1.zip
|       ├── ImportedFile2.zip
|       ├── segments.gen
|       ├── segments_N
|       ├── _1.si
├── UserId2/
│   ├── Project1/
|       ├── ImportedFile1.zip
|       ├── ImportedFile2.zip
|       ├── segments.gen
|       ├── segments_N
|       ├── _1.si

Пользователь может создавать несколько проектов, и каждый из них может импортировать несколько файлов ZIP.

Теперь, как лучше всего создать и поддерживать объекты IndexWriter и IndexSearcher?

Я использую Lucene. Net .Store. Azure Пакет как мой каталог индекса - azure хранилище BLOB-объектов.

Через мои POC я обнаружил, что открытие Azure Directory - очень дорогая операция. Вот мой код:

var azDir = new AzureDirectory(
                    CloudStorageAccount.Parse(azureStorageConnectionString),
                    $"{containerName}/{userId}/{projectId}",
                    new RAMDirectory());

var azureBlobIndexReader = DirectoryReader.Open(azDir); // takes very long time !!!
var indexSearcher = new IndexSearcher(azureBlobIndexReader);

Другой вариант - использовать объект indexWriter для получения indexReader и из него создать IndexSearcher, как показано ниже:

var azDir = new AzureDirectory(
                    CloudStorageAccount.Parse(azureStorageConnectionString),
                    $"{containerName}/{userId}/{projectId}",
                    new RAMDirectory());
var indexWriterConfig =
                    new IndexWriterConfig(
                            LuceneVersion.LUCENE_48,
                            new StandardAnalyzer(LuceneVersion.LUCENE_48))
                        .SetOpenMode(OpenMode.CREATE_OR_APPEND);

var indexWriter = new IndexWriter(azureDir, indexWriterConfig);
var reader = writer.GetReader(true);
writer.Dispose();
var indexSearcher = new IndexSearcher(reader);

Приведенный выше подход был значительно быстрее.

Требование заключается в том, что пользователь должен иметь возможность импортировать файл (извлечение zip-файла, анализ дочерних файлов и индексирование), и пока он выполняется, он должен иметь возможность поиска среди уже импортированных файлы.

  1. Должен ли я создавать один одноэлементный объект IndexWriter для проекта и использовать его как для индексации, так и для поиска?
  2. Если да, то что это за лучший способ управлять таким количеством IndexWriters? Шаблон пула объектов? Будет ли это эффективно, как нет. проектов продолжает расти?
  3. Почему второй подход к созданию indexSearcher был быстрее, чем DirectoryReader.Open (AzureDirectory)?
...