CouchBase Lite, исключить документы с определенными ключами в запросе

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

    com.couchbase.lite.View view = database.getView(VIEW_NAME);
    if (view.getMap() == null) {
        Mapper map = new Mapper() {
            @Override
            public void map(Map<String, Object> document, Emitter emitter) {
                if ("user".equals(document.get("type"))) {
                    emitter.emit(document.get("name"), document); 
                }
            }
        };
        view.setMap(map, null);
    }

Имея это представление, я могу создавать на нем запросы с определенными параметрами, такими как setKeys, startKey, endKey, setDescending, setDescending, setSkip и другими, как описано в Couchbase руководство.

если я напишу

    Query query = view.createQuery();
    List<Object> keys = new ArrayList<>();
    keys.add("User Name");
    query.setKeys(keys);

этот запрос вернет все документы, соответствующие ключу «Имя пользователя».

Но я не смог найти простой способ написать запросы, которые исключают (опускают) документы с определенными ключами (например, напротив функции setKeys())

один взлом был обнаружен в Пример ToDoLite Код выглядит следующим образом:

public static Query getQuery(Database database, final String ignoreUserId) {
    com.couchbase.lite.View view = database.getView(VIEW_NAME);
    if (view.getMap() == null) {
        Mapper map = new Mapper() {
            @Override
            public void map(Map<String, Object> document, Emitter emitter) {
                if ("user".equals(document.get("type"))) {
                    if (ignoreUserId == null ||
                            (ignoreUserId != null &&
                                    !ignoreUserId.equals(document.get("user_id")))) {
                        emitter.emit(document.get("name"), document);
                    }
                }
            }
        };
        view.setMap(map, null);
    }

    Query query = view.createQuery();
    return query;
}

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

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

Вы знаете какое-нибудь лучшее решение или хак?

Приветствуется любая помощь
Заранее спасибо


person Andriy Bas    schedule 23.07.2014    source источник


Ответы (1)


CouchBase не предназначен для типов запросов, которые вы хотите задать здесь. Он предназначен для скрытого использования map/reduce для идентификации конкретных документов с диапазоном (вплоть до диапазона 1 документа), а не для исключения конкретных документов. То, что вы просите, не будет эффективным в CouchBase. Вы используете неправильную технологию, если ваша цель — эффективно выполнять такие запросы.

Однако, если у вас связаны руки и вы привязаны к CouchBase Lite, вам придется работать с теми типами запросов, которые у вас есть. Исключение определенного значения может быть переформулировано как включение всех других значений. Если вы хотите сделать это в CouchBase, вы используете диапазонные запросы с диапазонами, разработанными так, чтобы не включать значение, которое вы хотите исключить.

Вот краткий концептуальный пример. Предположим, что в вашем представлении есть документы с ключами "A", "B", "C", "D", "F" и "X", и вы хотите выполнить запрос, результат которого исключает документ "D". Вы можете получить желаемый результат, сначала выполнив запрос диапазона для "A"-"C", а затем выполнив второй запрос диапазона для "E"-"Z". Два объединенных результата будут всем, кроме «D».

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

person hrunting    schedule 03.08.2014
comment
большое спасибо за ответ, похоже тема не слишком популярна - person Andriy Bas; 04.08.2014
comment
@hrunting stackoverflow.com/questions /36598905/ - person Yashvit; 14.04.2016
comment
Этот ответ абсолютно неверен. Именно здесь N1QL Couchbase Internal SQL Like Query Language прыгает. - person frank-dspeed; 01.06.2016
comment
@FrankfromDSPEED По состоянию на июнь 2016 года Couchbase Lite не поддерживает использование N1QL. - person hrunting; 06.06.2016
comment
Добавление соответствующего обновления. В версии 2.0 Couchbase Lite будет поддерживать динамические запросы (то есть N1QL). - person Hod; 20.07.2017