Да, вопрос сбивает с толку. Если вы знаете, как лучше спросить о том, о чем я прошу, поделитесь, пожалуйста!
Я разрабатываю независимый 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».
Это работает хорошо, за исключением случаев, когда несколько пользователей создаются одновременно с пустой базой данных. Этот дизайн индексации не является безсостоятельным, и поэтому он вызывает странные вещи.
Мой вопрос в том, как я могу улучшить этот дизайн? Я думал о паре решений, но у каждого из них есть несколько недостатков.
Создайте вторичный индекс (список с ключом «users:role:worker») с самого начала. Однако это кажется пустой тратой места, учитывая, что для каждого поля с индексом будут созданы две записи, что часто не нужно.
Вместо того, чтобы хранить идентификатор в качестве значения для каждого индекса, сохраните строковый массив идентификаторов. Это предотвратит создание этого вторичного списка. Новые идентификаторы пользователей будут просто добавлены в массив строк. Однако этот метод означает, что массив строк будет перезаписываться всякий раз, когда добавляется новый пользователь. Это наводит меня на мысль, что одновременные запросы просто перезапишут друг друга, что приведет к нежелательным результатам.
Как вы думаете? Есть ли лучший дизайн, чтобы справиться с этим?
Помощь и обратная связь очень ценятся!
Redisearch было бы здорово, но я использую Redis Enterprise Cloud для простого управления кластером или узлами, и он не интегрируется с Redisearch (по состоянию на весну 2019 года).
Если вы являетесь пользователем Redis Cloud Pro, он должен быть встроен в docs.redislabs.com/latest/rv.
Хороший звонок, но я сейчас использую только базовую версию. Pro немного дороже. Я мог бы обновиться, как только продукт будет запущен и принесет прибыль. RediSearch — зверь, который также предлагает множество других замечательных функций.
Essentials теперь поддерживает все модули Redis Labs, включая RediSearch.





В итоге я сделал решение №1 с изюминкой, и оно работает хорошо. Вместо того, чтобы устанавливать спецификацию схемы на index: true для этого конкретного поля, я установил deepIndex: true, который автоматически создает вторичный индекс с самого начала.
Это означает, что любое поле, которое, вероятно, будет иметь общие значения между несколькими экземплярами, будет таким образом «глубоко проиндексировано».
Рассматривали ли вы возможность использования RediSearch? redisearch.io Он имеет именно такое поведение «Тегов», см.: oss.redislabs.com/redisearch/Tags.html