Получить все элементы массива, если дочерний массив содержит определенный элемент в JSON/RediSearch

Я использую 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"
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
0
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Это ошибка в ранних диалектах поиска, которая не была исправлена ​​в целях сохранения обратной совместимости. Вам нужно указать Поиску использовать как минимум 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

Кроме того, есть удобная веб-страница со всей основной информацией о диалекте, которую вам может быть интересно узнать.

Я не был в курсе. Еще одно уточнение: диалект инкрементальный, не так ли? Поэтому, если у меня есть новое приложение, было бы целесообразно указать DEFAULT DIALECT 5, которое является последним, поскольку проблем с ретро-совместимостью быть не может.

Andrea Nicolai 25.06.2024 08:41

Для основной версии 2 да, это может быть полезно. Ни одна диалектная версия не будет удалена. Просто обратите внимание: когда появляется новый диалект, это означает, что некоторые запросы будут анализироваться по-другому или возвращать другую структуру ответа. При изменении версии диалекта вам следует убедиться, что вы получаете ожидаемые результаты.

A. Guy 26.06.2024 19:08

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