Я использую Redis с модулем RedisJSON и RediSearch, и у меня есть несколько записей, подобных приведенным ниже.
JSON.SET uuid_1 $ '{ "type": "game1", "players": ["player1", "player2"] }'
JSON.SET uuid_2 $ '{ "type": "game1", "players": ["player3", "player2"] }'
Чего я хочу добиться, так это своего рода запрос, который возвращает как uuids, так и весь массив, когда такой массив содержит некоторые целевые элементы.
Например, когда я запрашиваю:
player1
-> [uuid_1
, ["игроки", ["игрок1", "игрок2"] ]player2
-> [uuid_2
, ["игроки", ["игрок3", "игрок2"]].Я также проверил этот ответ, но не могу полностью воспроизвести его в своем случае.
Что мне удалось получить, так это сначала создать индекс:
FT.CREATE idx ON JSON SCHEMA '$.players[*]' AS players TAG $.type AS gameType TEXT
а затем либо получить только uuids:
127.0.0.1:6379> FT.SEARCH idx @players:{player2} NOCONTENT
1) (integer) 2
2) "uuid_1"
3) "uuid_2"
или весь ключ
127.0.0.1:6379> FT.SEARCH idx @players:{player2}
1) (integer) 2
2) "uuid_1"
3) 1) "$"
2) "{\"type\":\"game1\",\"players\":[\"player1\",\"player2\"]}"
4) "uuid_2"
5) 1) "$"
2) "{\"type\":\"game1\",\"players\":[\"player3\",\"player2\"]}"
К сожалению, если я хочу получить только атрибут player
, это кажется неполным и возвращает мне только первый элемент:
127.0.0.1:6379> FT.SEARCH idx @players:{player2} RETURN 1 players
1) (integer) 2
2) "uuid_1"
3) 1) "players"
2) "player1"
4) "uuid_2"
5) 1) "players"
2) "player"
127.0.0.1:6379> FT.SEARCH idx @players:{player1} RETURN 1 players
1) (integer) 1
2) "uuid_1"
3) 1) "players"
2) "player1"
Это ошибка в ранних диалектах поиска, которая не была исправлена в целях сохранения обратной совместимости. Вам нужно указать Поиску использовать как минимум DIALECT 3, чтобы вернуть весь массив.
127.0.0.1:6379> FT.SEARCH idx @players:{player2} RETURN 1 players DIALECT 3
1) (integer) 2
2) "uuid_1"
3) 1) "players"
2) "[\"player1\",\"player2\"]"
4) "uuid_2"
5) 1) "players"
2) "[\"player3\",\"player2\"]"
127.0.0.1:6379> FT.SEARCH idx @players:{player1} RETURN 1 players DIALECT 3
1) (integer) 1
2) "uuid_1"
3) 1) "players"
2) "[\"player1\",\"player2\"]"
Вы можете установить диалект по умолчанию при запуске Redis или задав параметр конфигурации во время работы Redis:
$ redis-server --loadmodule ./redisearch.so DEFAULT_DIALECT 3
FT.CONFIG SET DEFAULT_DIALECT 3
Кроме того, есть удобная веб-страница со всей основной информацией о диалекте, которую вам может быть интересно узнать.
Для основной версии 2 да, это может быть полезно. Ни одна диалектная версия не будет удалена. Просто обратите внимание: когда появляется новый диалект, это означает, что некоторые запросы будут анализироваться по-другому или возвращать другую структуру ответа. При изменении версии диалекта вам следует убедиться, что вы получаете ожидаемые результаты.
Я не был в курсе. Еще одно уточнение: диалект инкрементальный, не так ли? Поэтому, если у меня есть новое приложение, было бы целесообразно указать
DEFAULT DIALECT 5
, которое является последним, поскольку проблем с ретро-совместимостью быть не может.