Spec-Zone.ru › RethinkDB ruby

Команда ReQL: filter

Синтаксис команды

selection.filter(predicate_function[, :default => false]) → selection
stream.filter(predicate_function[, :default => false]) → stream
array.filter(predicate_function[, :default => false]) → array

Описание

Возвращает все элементы в последовательности, для которых заданный предикат истиннен. Результат filter будет таким же, как вход (последовательность, поток или массив). Документы могут быть отфильтрованы различными способами — диапазоны, вложенные значения, булевы условия и результаты анонимных функций.

По умолчанию, filter будет молча пропускать документы с отсутствующими полями: если предикат пытается получить доступ к полю, которого нет (например, предикат {:age => 30} применён к документу без поля age ), этот документ не будет возвращен в результате, и ошибка не будет сгенерирована. Это поведение можно изменить с помощью необязательного аргумента default.

  • Если default установлено в true, документы с отсутствующими полями будут возвращены, а не пропущены.
  • Если default установлено в r.error(), будет выброшена ReqlRuntimeError при проверке документа с отсутствующим полем.
  • Если default установлено в false (по умолчанию), документы с отсутствующими полями будут пропущены.

Примечание: filter не использует вторичные индексы. Для извлечения документов через вторичные индексы рассмотрите команды get_all, between и eq_join.

Основные предикаты

Пример: Получить всех пользователей, которым 30 лет.

r.table('users').filter({:age => 30}).run(conn)

Предикат {'age': 30} выбирает документы в таблице users с полем age, значение которого равно 30. Документы с полем age, установленным на любое другое значение или с отсутствующим полем age пропускаются.

Хотя стиль предиката {'field': value} полезен для точных совпадений, более общий способ написания предиката — использование блока Ruby, который возвращает true или false.

r.table('users').filter{ |user|
    user["age"].eq(30)
}.run(conn)

В этом случае функция возвращает true, если поле age равно 30.

Предикаты filter оцениваются на сервере и должны использовать выражения ReQL. Некоторые операторы сравнения Ruby перегружены драйвером RethinkDB и будут преобразованы в ReQL, такие как ==, </> и |/& (обратите внимание на односимвольный формат, а не ||/&&).

Также предикаты должны оценивать поля документов. Они не могут оценивать вторичные индексы.

Пример: Получить всех пользователей, которым больше 18 лет.

r.table("users").filter{ |user|
    user["age"] > 18
}.run(conn)

Пример: Получить всех пользователей, которым меньше 18 лет и больше 13 лет.

r.table("users").filter{ |user|
    (user["age"] < 18) & (user["age"] > 13)
}.run(conn)

Пример: Получить всех пользователей, которым больше 18 лет или которые дали согласие родителей.

r.table("users").filter{ |user|
    (user["age"] >= 18) | (user["hasParentalConsent"])
}.run(conn)

Более сложные предикаты

Пример: Получить всех пользователей, которые подписались между 1 января 2012 года (включительно) и 1 января 2013 года (исключительно).

r.table("users").filter{ |user|
    user["subscription_date"].during(r.time(2012, 1, 1, 'Z'),
        r.time(2013, 1, 1, 'Z'))
}.run(conn)

Пример: Получить всех пользователей, у которых есть почтовый ящик gmail (поле email заканчивается на @gmail.com).

r.table("users").filter{ |user|
    user["email"].match("@gmail.com$")
}.run(conn)

Пример: Фильтр на основе наличия значения в массиве.

Предполагая следующую схему для таблицы users:

{
    :name => String
    :places_visited => [String]
}

Получить всех пользователей, чей поле places_visited содержит France.

r.table("users").filter{|user|
    user["places_visited"].contains("France")
}.run(conn)

Пример: Фильтр на основе вложенных полей.

Предполагая следующую схему для таблицы users:

{
    :id => String
    :name => {
        :first => String,
        :middle => String,
        :last => String
    }
}

Получить всех пользователей с именем «Вильям Адама» (имя «Вильям», фамилия «Адама»), с любым отчеством.

r.table("users").filter({
    :name => {
        :first => "William",
        :last => "Adama"
    }
}).run(conn)

Если вам нужно точное совпадение для поля, являющегося объектом, вам придется использовать r.literal.

Получить всех пользователей с именем «Вильям Адама» (имя «Вильям», фамилия «Адама»), у которых нет отчества.

r.table("users").filter(r.literal({
    :name => {
        :first => "William",
        :last=> "Adama"
    }
})).run(conn)

Вы можете переписать их с помощью блоков.

r.table("users").filter{ |user|
    (user["name"]["first"].eq("William")) &
    (user["name"]["last"].eq("Adama"))
}.run(conn)
r.table("users").filter{ |user|
    user["name"].eq({
        :first => "William",
        :last => "Adama"
    })
}.run(conn)

Обработка отсутствующих полей

По умолчанию, документы с отсутствующими полями, проверенными предикатом filter , пропускаются. В предыдущих примерах пользователи без поля age не возвращаются. Передав необязательный аргумент default к filter, вы можете изменить это поведение.

Пример: Получить всех пользователей младше 18 лет или у которых отсутствует поле age.

r.table("users").filter(:default => true){ |user| user["age"] < 18 }.run(conn)

Пример: Получить всех пользователей старше 18 лет. Выбросить ошибку, если у документа отсутствует поле age.

r.table("users").filter(:default => r.error()){
    |user| user["age"] > 18
}.run(conn)

Пример: Получить всех пользователей, которые указали номер телефона (все документы, у которых поле phone_number существует и не равно nil).

r.table('users').filter{ |user|
    user.has_fields('phone_number')
}.run(conn)

Пример: Получить всех пользователей с ролью «редактор» или привилегией «админ».

r.table('users').filter{ |user|
    user['role'].eq('editor').default(false) |
        user['privilege'].eq('admin').default(false)
}.run(conn)

Вместо использования необязательного аргумента default к filter, мы должны использовать значения по умолчанию для полей в рамках условия or . Почему? Если поле слева от условия or отсутствует в документе — в данном случае, если у пользователя нет поля role — предикат сгенерирует ошибку и вернет false (или значение, установленное аргументом default ), не оценивая правую часть условия or. Используя .default(false) для полей, каждая сторона условия or будет оцениваться либо как значение поля, либо как false , если поле отсутствует.

Связанные команды

  • get
  • get_all
  • between

© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/api/ruby/filter/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API