Поиск Azure в неограниченном массиве дочерних объектов, полученных из Космоса - PullRequest
0 голосов
/ 10 октября 2019

Требование

У меня есть модель данных, в которой каждая «вещь» имеет несколько дочерних элементов и может быть представлена ​​в виде JSON следующим образом.

{
    "id": "1",
    "name": "parent_1",
    ... other parent fields ...
    "children": [
        {
            "id": "1_a",
            "name": "child_1_a"
            ... other child fields ...
        },
        {
            "id": "1_b",
            "name": "child_1_b"
            ... other child fields ...
        }
    ]
}

Требование состоит в том, чтобы мы нашли все родительские объекты, которые содержат детей, чей name соответствует определенному шаблону.

Ограничения

У нас есть различные ограничения:

  1. Мы должны хранить данные в Cosmos с помощью SQL API.
  2. Мы можем использовать только поиск Azure.

Задача

В идеале, мы должны хранить каждую родительскую "вещь" как целый документв космосе со всеми своими детьми. Однако может быть много дочерних элементов, означающих, что размер документа иногда превышает ограничение в 2 МБ для документов Cosmos.

То, что я пробовал

Попытка 1

В качестве альтернативы можно хранить отдельные родительские и дочерние документы в одной коллекции Azure Cosmos, отличать родителей от детей с помощью поля type и ссылаться на родителя с помощью поля id. Например,

Родитель

{
    "id": "1",
    "name": "parent_1",
    "type": "parent"
}

Ребенок 1

{
    "id": "1_a",
    "name": "child_1_a",
    "type": "child",
    "parentId": "1"
}

Ребенок 2

{
    "id": "1_b",
    "name": "child_1_b",
    "type": "child",
    "parentId": "1"
}

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

Попытка 2

Я подумал, что мог бы использовать JOIN в Cosoms для заполнения поиска Azure. Однако для этого потребуются перекрестные объединения документов, которые не поддерживаются.

Другие альтернативы

Другие предложения, которые я видел:

  • Фасет по идентификатору родителя, но я читал, что это будет работать плохо.

  • Дробить детей в партии (например, 500 детей) и прикреплять каждую партиюродителю. Если существует несколько пакетов для одного родителя, то денормализуйте поля для родителя. В настоящее время это единственная опция, которая работает с текущими данными, хотя, похоже, она просто задерживает проблему - например, в какой-то момент возможно, что количество пакетов станет достаточно большим, чтобы еще раз снизить производительность поиска.

Вопрос

Можно ли использовать Cosmos (SQL-API) и Azure Search для этого требования, и если да, то как?

1 Ответ

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

Почему бы вам не сохранить в Azure Поиск всех дочерних элементов как отдельных документов, а затем просто добавить другое свойство с необходимой родительской информацией:

{
            "id": "1_a",
            "name": "child_1_a"
            ... other child fields ...,
            "parent": {
                 "parentId":123,
                 "parentName":"x"
                  ... other parent fields ...,
            }    
}

Ваши запросы также должны быть упрощены (в моеммнение).

...