Spec-Zone.ru › RethinkDB javascript

Команда 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 не использует вторичные индексы. Для извлечения документов через вторичные индексы рассмотрите getAll, between и eqJoin.

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

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

r.table('users').filter({age: 30}).run(conn, callback);

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

Хотя стиль предиката {field: value} полезен для точных совпадений, более общий способ записи предиката — использование команды row с оператором сравнения, например, eq или gt, или использование анонимной функции, которая возвращает true или false.

r.table('users').filter(r.row("age").eq(30)).run(conn, callback);

В этом случае предикат r.row("age").eq(30) возвращает true, если поле age равно 30. Вы можете записать этот предикат как анонимную функцию:

r.table('users').filter(function (user) {
    return user("age").eq(30);
}).run(conn, callback);

Предикаты filter оцениваются на сервере и должны использовать выражения ReQL. Вы не можете использовать стандартные операторы сравнения JavaScript, такие как ==, </> и ||/&&.

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

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

r.table("users").filter(r.row("age").gt(18)).run(conn, callback)

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

r.table("users").filter(
    r.row("age").lt(18).and(r.row("age").gt(13))
).run(conn, callback);

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

r.table("users").filter(
    r.row("age").ge(18).or(r.row("hasParentalConsent"))
).run(conn, callback);

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

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

r.table("users").filter(function (user) {
    return user("subscriptionDate").during(
        r.time(2012, 1, 1, 'Z'), r.time(2013, 1, 1, 'Z'));
}).run(conn, callback);

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

r.table("users").filter(function (user) {
    return user("email").match("@gmail.com$");
}).run(conn, callback);

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

Предположим, такая схема для таблицы users:

{
    name: String
    placesVisited: [String]
}

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

r.table("users").filter(function(user) {
    return user("placesVisited").contains("France")
}).run( conn, callback)

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

Предположим, такая схема для таблицы users:

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

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

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

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

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

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

Вы можете переписать это с помощью анонимных функций.

r.table("users").filter(function(user) {
    return user("name")("first").eq("William")
        .and(user("name")("last").eq("Adama"));
}).run(conn, callback);

r.table("users").filter(function(user) {
    return user("name").eq({
        first: "William",
        last: "Adama"
    });
}).run(conn, callback);

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

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

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

r.table("users").filter(
    r.row("age").lt(18), {default: true}
).run(conn, callback);

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

r.table("users").filter(
    r.row("age").gt(18), {default: r.error()}
).run(conn, callback);

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

r.table('users').filter(function (user) {
    return user.hasFields('phoneNumber');
}).run(conn, callback);

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

r.table('users').filter(function (user) {
    return (user('role').eq('editor').default(false).
        or(user('privilege').eq('admin').default(false)));
}).run(conn, callback);

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

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

  • get
  • getAll

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

Spec-Zone.ru

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