Получение случайной записи от объекта Objectify - PullRequest
3 голосов
/ 31 октября 2011

Как я могу получить случайный элемент из хранилища данных Google App Engine с помощью Objectify ?Должен ли я получить все ключи объекта и выбрать случайным образом из них или есть лучший способ?

Ответы [ 4 ]

2 голосов
/ 01 ноября 2011

Назначьте случайное число от 0 до 1 каждому объекту при его сохранении.Чтобы получить случайную запись, сгенерируйте другое случайное число от 0 до 1 и запросите наименьший объект со случайным значением, превышающим это.

0 голосов
/ 31 октября 2017

Я в значительной степени адаптирую алгоритм, предоставленный Matejc.Тем не менее, 3 вещи:

  1. Вместо использования count () или фабрики обслуживания хранилища данных (DatastoreServiceFactory.getDatastoreService ()), у меня есть сущность, которая отслеживает общее количество сущностейчто меня интересует. Причина такого подхода в том, что:count () может быть дорогим, когда вы имеете дело с большим количеством объектов b.Вы не можете проверить фабрику службы хранилища данных локально ... тестирование в prod это просто плохая практика.

  2. Генерация случайного числа: ThreadLocalRandom.current (). NextLong (1, maxRange)

  3. Вместо использования limit () я использую смещение, поэтому мне не нужно беспокоиться о «сортировке».

0 голосов
/ 06 февраля 2013

Цитируется из этого поста о выборе некоторых случайных элементов из объективированного хранилища данных:

Если ваши идентификаторы последовательны, одним из способов будет случайный выбор 5 числа из диапазона идентификаторов, которые, как известно, используются. Затем используйте запрос с Фильтр "in" ().

Если вы не возражаете против 5 соседних записей, вы можете использовать count (), limit () и offset () для случайного поиска блока из 5 записей.

В противном случае вам, вероятно, потребуется использовать limit () и offset () для случайным образом выбирайте одну запись за раз.

- Джош

0 голосов
/ 13 ноября 2011

Вам не нужно получать все. Например:

  1. countall = query (X.class) .count () // http://groups.google.com/group/objectify-appengine/browse_frm/thread/3678cf34bb15d34d/82298e615691d6c5?lnk=gst&q=count#82298e615691d6c5
  2. rnd = Создать случайное число [0..countall]
  3. ofy.query (X.class) .order ("- дата"). Limit (rnd); // например -дата или какое-то хроническое индексированное поле
  4. Последний идентификатор ваш ... (в среднем вы набираете 50% или, по крайней мере, первое чтение в среднем на 50% меньше)

Улучшения (чтобы иметь меньшую таблицу ключей в кеше)!

После первого прочтения запомните все элементы X. Кэширование id-ов и их позиции. Поэтому в следующий раз условие запроса от выбранного идентификатора будет дальше (максимум ".limit (rnd% X)" будет X-1).

Случайный случай - просто случайный, если он не должен быть близким к 100% справедливому, предположите значение хронического поля (например, если у вас есть 1000 записей за 10 дней, для случайных 501 выберите второй элемент больше пятого дня).

Другие варианты, если у вас есть хроническая дата поля (или аналогичная), выборка элементов старше, чем случайная дата и младше, чем случайная дата + 1 (вам нужно знать первую дату и последнюю дату). Во-вторых выберите случайных между извлеченными записями. Если запрос пуст, выберите больше, чем etc ...

...