JDOQL (Appengine) - Запрос для всех / одного элемента со списком в качестве параметра? - PullRequest
1 голос
/ 21 февраля 2011

Я пытаюсь создать запрос, чтобы все элементы данного списка (параметра) содержались в столбце таблицы (который также является списком). Мне также нужен запрос, чтобы в столбце таблицы содержался хотя бы один элемент из данного списка (параметра). Например:

СДО:

Table: User
| ID | Name | Interests <List of Strings> |

Запрос:

List <String> gifts; // Item to query with
  1. Как я могу сделать запрос для всех пользователей, чьи интересы соответствуют ВСЕМ подаркам? Т.е. ВСЕ подарки должны быть подмножеством Интересов.

  2. Как я могу сделать запрос для всех пользователей, чьи интересы совпадают с НЕКОТОРЫМ (хотя бы одним) подарком? т.е. хотя бы один подарок является подмножеством интересов.

  3. Как я могу сделать запрос для всех пользователей, чьи ВСЕ интересы совпадают с подарками? все интересы должны быть подмножеством подарков.

  4. Как я могу сделать запрос для всех пользователей, чьи НЕКОТОРЫЕ (хотя бы одно) интересы совпадают с подарками? то есть, по крайней мере, один интерес представляет собой подмножество подарков.

Возможны ли эти запросы? Если так то как? Могу ли я использовать ключевое слово .contains() для выполнения этих запросов? Если так, то как? Кто-нибудь может поделиться некоторыми примерами? Любая помощь будет принята с благодарностью.

Спасибо.

1 Ответ

0 голосов
/ 22 февраля 2011

Чтобы понять, как эти запросы работают (или не работают), важно понять, как хранилище данных индексирует сущности. Когда вы вставляете сущность со свойством списка, хранилище данных разбивает каждую запись списка на отдельную строку индекса. Например, следующая сущность:

Entity(User):
  id=15
  name="Jim"
  interests=["Drinking", "Banjos"]

В результате автоматические индексы приведут следующие записи индекса:

(User, "id", 15, Key("User", 1))
(User, "name", "Jim", Key("User", 1))
(User, "interests", "Drinking", Key("User", 1))
(User, "interests", "Banjos", Key("User", 1))

Если вы также определили составной индекс (имя, интересы), записи в нем будут выглядеть примерно так:

("Jim", "Drinking", Key("User", 1))
("Jim", "Banjos", Key("User", 1))

После этого мы можем обратиться к вашим конкретным запросам в следующем порядке:

  1. Это невозможно, поскольку каждая запись находится в отдельной строке индекса. Вы можете индексировать это, создав список с одной записью для каждого подмножества интересов, и выполнить запрос на равенство, но он быстро растет с увеличением количества интересов, поэтому, вероятно, будет плохой идеей, если вы ожидаете, что у пользователя будет больше скажем, 5 интересов, или если вы не можете наложить больше ограничений на проблему.
  2. Вы можете использовать фильтр «IN» - например, «SELECT * FROM пользователя, ГДЕ ИНТЕРЕСУЕТСЯ В [« Drinking »,« Banjos »]» - он будет соответствовать любой записи, в которой есть хотя бы один из «Drinking» и «Banjos» как интересы. Обратите внимание, что это будет разбито на несколько подзапросов равенства в SDK, поэтому это эквивалентно выполнению столько запросов, сколько у вас есть записей в списке запросов.
  3. Это обратное значение 1. Опять же, это не очень практично, если вы не сохранили полный (отсортированный) список интересов в виде строки и не готовы выполнить отдельный запрос для каждого подмножества вашего списка подарков.
  4. Если я не ошибаюсь, это то же самое, что и 2 - вы ищете какое-либо пересечение между двумя наборами, что является симметричной операцией.

Для чисел 1 и 3 вы можете обойтись, применив более грубый фильтр, например, выполнив поиск по одному или двум интересам, и отфильтровав результаты в памяти для точных совпадений.

...