Фильтрация результатов MongoDB после того, как Elasticsearch возвращает идентификаторы документов - PullRequest
0 голосов
/ 23 октября 2019

У меня есть коллекция документов в MongoDB, и подмножество этих документов проиндексировано в Elasticsearch для целей поиска. Я использую пользовательскую функцию оценки на ES, а индексированный json в основном используется для оценки. После того, как у меня есть отсортированный список документов, меня действительно интересует получение этих полных документов из MongoDB (поэтому ES используется для возврата списка идентификаторов, которые я затем запросю в MongoDB с использованием фильтра { "$in" => "_id": [...]}).

Проблема в том, что документы, проиндексированные на Elasticsearch, могут быть синхронизированы неправильно, и когда я получаю список результатов изasticsearch, появляются некоторые документы, которые нежелательны (например, неопубликованные данные и т. Д.)

Итак, что я хотел бы сделать, это «отфильтровать» этот список идентификаторов в соответствии с условиями, основанными на их атрибутах: как минимум 6 атрибутов должны иметь определенное значение, которое всегда одинаково, то есть один атрибут долженбыть "ненулевым", другой ложным и т. д.). Я думал, что смогу добиться этого, используя фильтр частичного индекса, но я не могу создать дублированный индекс, используя другое выражение частичного фильтра (в противном случае, я бы просто добавил еще один индекс { _id: 1 } с partialFilterExpression: { "my_field": true, ... }, который мне подходит)

Как лучше всего это сделать?

Конкретный сценарий

Предположим, что эти документы проиндексированы в MongoDB с атрибутами "опубликовано" / "скрыто", относящимися к моему поиску. действие (я не хочу показывать неопубликованные или скрытые документы)

{ _id: "1...", "created_at": "2019-01-20", "published": true, "hidden": false}
{ _id: "2...", "created_at": "2019-02-20", "published": false, "hidden": false}
{ _id: "3...", "created_at": "2029-03-20", "published": true, "hidden": false}
{ _id: "4...", "created_at": "2029-03-20", "published": false, "hidden": false}
{ _id: "5...", "created_at": "2029-03-20", "published": false, "hidden": true}

Когда пользователь выполняет поиск данных с нашей реализацией ES, Elasticsearch запускает функцию оценки и возвращает оценки каждого документа (здесьв примере предполагается, что извлекается только документ 1-3) Из-за несинхронизированных проблем может быть возвращен неопубликованный документ (2)

{ _id: "1...", "score": 1}
{ _id: "2...", "score": 2}
{ _id: "3...", "score": 3}

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

{ _id: "1...", "created_at": "2019-01-20", "published": true, "hidden": false}
{ _id: "3...", "created_at": "2029-03-20", "published": true, "hidden": false}

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

Есть ли хитрость, чтобы сделать это, возможно, с использованиемpartalIndex? Здесь сценарий прост, потому что у меня просто "published": false, "hidden": true, но мои условия на самом деле немного сложнее, как упомянуто выше, и было бы бесполезно получать все эти документы и затем фильтровать их вместо того, чтобы только извлекать документы, отфильтрованные просточтение «отфильтрованного индекса» идентификаторов, чтобы увидеть, есть эти идентификаторы или нет.

1 Ответ

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

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

Я хотел выполнить какой-либо текстовый поиск и отобразить результаты перед пользователями в соответствии с релевантностью результата.

Раньше мы использовали для этого простое регулярное выражение Монго, но затем мы решили сделать то же самое с ElasticSearch.

Однако этот результат также основан на других факторах и атрибутах в моем случае (которые простонекоторые поля и пользовательские данные).

Вот мой подход (я объясню это на фиктивном примере).

Рассмотрим систему статей, где у пользователя есть свои собственные написанные статьи, онможет писать больше статей, если он хочет, чтобы они могли публиковать их, если они не опубликованы, они находятся в состоянии ПРОЕКТ, если активировано, тогда статья будет в состоянии АКТИВИРОВАН, и он может читать некоторые статьи, предоставленные владельцами системы. Также пользователь может поделитьсяего статьи с другими.

Таким образом, типичный дизайн БД будет выглядеть следующим образом:

{
   articleType: Custom or System,
   status: DRAFT, DEACTIVATED, ACTIVATED,
   ownerId: unique id of the owner,
   sharedWith: [unique ids of shared with users],
   title: title of the article,
   articleText: text description of the article,
   tags: some tags related to article

}

и некоторые другие полезные поля.

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

Итак, в соответствии с запросом mongo, я сначала экспортировал все необходимые поля в индекс ElasticSeach.

Затем я подготовил точно такой же запрос в ElasticSeach, когда мы выполняли поиск с помощьюзапрос монго.

т.е. мой запрос монго и запрос Elasticsearch были абсолютно одинаковыми.

Я удалил стоп-слова из текста поиска.

Я выполнил поиск в ElasticSearch только при наличии текста поиска, в противном случае я использовал только результаты монго.

здесь также реализована нумерация страниц.

Я создал текстовый индекс для коллекции mongo.

Стратегия такова: всякий раз, когда возникает ошибка из-за ElasticSeach или Cluster, возникает проблема тайм-аута. будет выполнять текстовый запрос на монго.

При использовании поиска статей с некоторым текстом, я выполнил поиск по ElasticSeach, также с помощью limit и skip, и получил _id и индекс каждого документа.

Когда я получил результат от ElastcSeach, я преобразовал _ids в ObjectId, у меня уже есть запрос монго, я добавил этот массив _ids (из ElasticSeach) в запрос, например:

{$and: [{_id: {$in : _idsFromES}} , ...remaining query]}

Я получаю точно такой же результатот Монго также,

Результаты слишком удовлетворительны и желательны для меня.

Кроме того, с этим я также обработал, удалить, вставить, обновление статьи,то же самое изменится и в ElasticSeach Index.

Таким образом, они всегда были в курсе.

Я надеюсь, что это поможет вам найти лучший способ выполнить вашу задачу. : -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...