Запросить случайную строку в ndb

Я пытаюсь разработать веб-приложение на движке приложений Google с помощью webapp2.

Одна из вещей, которые мне нужно сделать, - это получить случайное значение из ndb и отобразить его. Есть ли какой-нибудь эффективный метод, который позволяет мне это сделать?


person Jun Hao    schedule 25.06.2013    source источник
comment
возможный дубликат получения случайной записи из Google App Engine Хранилище данных?   -  person Sebastian Kreft    schedule 25.06.2013


Ответы (3)


Я предполагаю, что вы имеете в виду случайную запись, когда говорите «случайно из ndb».

Если вы используете автоматические идентификаторы, вы можете использовать следующий подход. (насколько редкие ваши идентификаторы повлияют на то, насколько успешным это будет).

используйте random.randrange(start, stop) со значением start равным 0, а не значением (2 ^ 52) -1, учитывая новую политику распределения идентификаторов.

сделать запрос ключей только для ключей больше, чем ключ, созданный из случайного идентификатора. если результатов нет, попробуйте получить ключи ‹ключ создан.

получить 10 (или некоторое количество) ключей

сделать случайный выбор random.choice(seq) для последовательности ключей, возвращенных из более ранней выборки.

key.get () выбранная запись.

Альтернатива для небольшого количества организаций, скажем, ‹1000

выполните запрос только ключей и вызовите все ключи, затем выполните random.choice() в списке ключей и db.get () для выбранного ключа. Это будет намного быстрее, чем любое решение для создания петель. Если вы делаете это часто и набор объектов для выбора не меняется часто, а размер списка ключей меньше 1 МБ, вы можете кэшировать ключи в memcache.

person Tim Hoffman    schedule 25.06.2013
comment
эй, следуя этому предложению ответа, я реализовал очень упрощенную версию, так как выборка с рандомным диапазоном и запрос для ключа ‹или› у меня не работали (либо пустое, либо то же значение). вот отрывок: 1. получить все ключи keys = Model.query().fetch(keys_only=True) 2. получить случайный ключ key = random.sample(keys, 1)[0] 3. получить объект: return key.get(). конечно, это можно было бы легко расширить для поддержки ряда сущностей. - person gru; 30.01.2014
comment
Насколько хорошо конкретный подход будет сильно зависеть от количества и разреженности выделенных идентификаторов. Тот факт, что вы можете получить все ключи в одном запросе, попадает в мое небольшое количество квалификаторов сущностей. Другой подход будет для миллионов и более ключей. - person Tim Hoffman; 30.01.2014

Есть зарезервированное свойство scatter. Я мало что знаю об этом, но он упоминается в реализации map / reduce.

person Guido van Rossum    schedule 25.06.2013
comment
Я не слишком уверен, что такое зарезервированное свойство scatter - person Jun Hao; 27.06.2013
comment
Вы пробовали поискать это в Google? - person Guido van Rossum; 04.07.2013
comment
Получить записи можно только из ndb, упорядоченных по свойству __scatter__. ndb не позволяет получить фактическое свойство AFAIK. Так что результаты всегда будут одинаковыми. В этом нет случайности. - person yaswanth; 27.08.2019

Если количество объектов в вашем хранилище данных не очень велико, вы можете использовать следующий подход: 1. Используйте yourquery = entitykind.query() для получения всех объектов.

2. Используйте yourquery.count(), чтобы получить количество сущностей

3. Используйте генератор случайных чисел, чтобы создать случайное число в пределах указанного выше значения счетчика.

4. Используйте цикл for для итерации по объектам, возвращаемым

yourquery.fetch ()

а затем, когда количество выполнений цикла равно вышеуказанному случайному числу, используйте конкретную сущность в своем веб-приложении.

person tony m    schedule 25.06.2013
comment
Это отлично работает для небольших наборов данных. Если у вас есть большое количество объектов, это не масштабируется. - person Tim Hoffman; 25.06.2013
comment
Даже для небольших наборов есть лучший способ - использовать offset = ‹random›, limit = 1. - person Guido van Rossum; 25.06.2013