Лучший способ сохранить индекс индекса с помощью Redis?

Да, вопрос сбивает с толку. Если вы знаете, как лучше спросить о том, о чем я прошу, поделитесь, пожалуйста!

Я разрабатываю независимый REST API, используя NodeJS и Redis. Сервер настроен на индексацию любых полей, которые настроены для этого в спецификации модели.

Бывший:

// user object
{ 
  firstName: 'Peter',
  lastName: 'Boyd',
  role: 'worker'
}

Сейчас, когда добавляется пользователь, индексируется поле «роль». База данных будет выглядеть так:

// user objects stored as regular key
key: "users:<ID1>" | value: "{ ...userData }"

// "role" indexes stored as hash key
hash key: "users:role" | field: "worker" | value: "users:<ID1>"

Когда добавляется второй пользователь, у которого также есть значение «рабочий» для поля «роль», база данных выглядит так:

// user objects stored as regular key
key: "users:<ID1>" | value: "{ ...userData1 }"
key: "users:<ID2>" | value: "{ ...userData2 }"

// "role" indexes stored as hash key (previous value gets replaced)
hash key: "users:role" | field: "worker" | value: "users:role:worker"

// "worker" value for "role" gets created as list
key: "users:role:worker" | value: [ "users:<ID1>", "users:<ID2>" ]

Таким образом, вторичный индекс не создается, если только он не требуется для экономии места. Вторичный индекс — это список, содержащий ключи пользовательских объектов. Начальное значение индекса содержит ключ этого списка в качестве его значения, которое в данном случае равно «users:role:worker».

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

Мой вопрос в том, как я могу улучшить этот дизайн? Я думал о паре решений, но у каждого из них есть несколько недостатков.

Возможное решение №1

Создайте вторичный индекс (список с ключом «users:role:worker») с самого начала. Однако это кажется пустой тратой места, учитывая, что для каждого поля с индексом будут созданы две записи, что часто не нужно.

Возможное решение №2

Вместо того, чтобы хранить идентификатор в качестве значения для каждого индекса, сохраните строковый массив идентификаторов. Это предотвратит создание этого вторичного списка. Новые идентификаторы пользователей будут просто добавлены в массив строк. Однако этот метод означает, что массив строк будет перезаписываться всякий раз, когда добавляется новый пользователь. Это наводит меня на мысль, что одновременные запросы просто перезапишут друг друга, что приведет к нежелательным результатам.


Как вы думаете? Есть ли лучший дизайн, чтобы справиться с этим?

Помощь и обратная связь очень ценятся!

Рассматривали ли вы возможность использования RediSearch? redisearch.io Он имеет именно такое поведение «Тегов», см.: oss.redislabs.com/redisearch/Tags.html

Guy Korland 19.05.2019 09:31

Redisearch было бы здорово, но я использую Redis Enterprise Cloud для простого управления кластером или узлами, и он не интегрируется с Redisearch (по состоянию на весну 2019 года).

user3386826 21.05.2019 01:59

Если вы являетесь пользователем Redis Cloud Pro, он должен быть встроен в docs.redislabs.com/latest/rv.

Guy Korland 21.05.2019 06:57

Хороший звонок, но я сейчас использую только базовую версию. Pro немного дороже. Я мог бы обновиться, как только продукт будет запущен и принесет прибыль. RediSearch — зверь, который также предлагает множество других замечательных функций.

user3386826 22.05.2019 02:23

Essentials теперь поддерживает все модули Redis Labs, включая RediSearch.

Guy Korland 03.12.2020 21:03
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
462
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В итоге я сделал решение №1 с изюминкой, и оно работает хорошо. Вместо того, чтобы устанавливать спецификацию схемы на index: true для этого конкретного поля, я установил deepIndex: true, который автоматически создает вторичный индекс с самого начала.

Это означает, что любое поле, которое, вероятно, будет иметь общие значения между несколькими экземплярами, будет таким образом «глубоко проиндексировано».

Другие вопросы по теме