Как использовать ИЛИ в представлении CouchDB

Я использую ruby ​​on rails и CouchDB, но у меня проблемы с просмотром CouchDB.

в sql я хочу:

выберите * от пользователя, где имя пользователя = ... или электронная почта = ... и статус = ...

Как создать такое представление?


person Haina    schedule 18.08.2011    source источник


Ответы (1)


Этот запрос представляет собой объединение ваших данных. (Нет, это не фактическое утверждение JOIN, но я имею в виду, что вы задаете 3 разных вопроса и «соединяете» результаты в ответе.)

Решение 1. Просто выполните запрос несколько раз.

Предположим, вы делаете 2 представления, значение равно status, а ключи такие:

  • by_username
  • by_email

Сохраняйте карту (Java) или словарь (Python), хэш (Perl), объект (Javascript) или любую другую структуру данных типа ключ/значение. Вы хотите сохранить набор соответствующих пользователей и добавить к нему.

Запросите каждое представление. Если статус то, что вам нужно, добавьте имена пользователей в свой набор. Когда все запросы выполнены, у вас есть полный ответ.

О нет! Но это так медленно! На самом деле очень часто решения медленные "в теории", но на самом деле они достаточно быстрые для требований. У вас есть сервер Rails. Вероятно, он имеет высокоскоростной доступ к CouchDB с малой задержкой (LAN). Каждый запрос в CouchDB — это всегда эффективное сканирование индекса. Итак, вы делаете 3 запроса, бам, бам, бам! Клиент запрашивает Rails через низкоскоростное соединение с высокой задержкой (Интернет), он, вероятно, этого не заметит.

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

Решение 2. Секретный запрос с несколькими ключами

CouchDB на самом деле поддерживает некоторые запросы «ИЛИ» к представлению. Дополнительные сведения см. в параметрах представления CouchDB.

Вам нужно одно представление для хранения всей информации. Я предлагаю ключи массива, [status, key_type, key_value]. Например, если у вас есть два пользователя, Алиса и Боб, ключи просмотра будут такими:

["reading" , "email"   , "[email protected]"]
["reading" , "username", "alice"]
["sleeping", "email"   , "[email protected]"]
["sleeping", "username", "bob"]

Как бы вы запросили status = "sleeping" and username = "X" or email = "Y"?

Это становится несколькими запросами к представлению, каждый с другим ключом:

key=["sleeping", "username", "X"]
key=["sleeping", "email"   , "Y']

К счастью, вы можете запрашивать несколько ключей одновременно.

POST /db/_design/example/_view/state_and_identifiers
Content-Type: application/json

{"keys": [ ["sleeping", "username", "X"]
         , ["sleeping", "email"   , "Y']
         ]
}

CouchDB вернет все результаты в одном ответе.

Резюме

Второе решение очень мощное, однако вам придется проделать большую работу, чтобы получить правильный запрос. И этот метод не может всегда удовлетворять любому SQL-запросу. SQL более эффективен для того, чтобы задать любой вопрос, который вы только можете придумать. Для CouchDB вы всегда должны научить его, что делать в первую очередь. Это неудобно. Но в результате запросы гарантированно выполняются быстро.

Учитывая неудобство решения 2, я лично предпочитаю решение 1. Можете ли вы сделать «присоединение» в CouchDB? Конечно! Соединения настолько просты. Просто сделайте несколько запросов, пока не получите нужные данные. Что делать, если вашему приложению нужно очень часто «присоединяться», а использование CouchDB сложно и содержит ошибки? Это явный признак того, что CouchDB может не подходить для вашего приложения.

person JasonSmith    schedule 19.08.2011
comment
+1, но я не понимаю, почему в решении 1 вы говорите 3 просмотра и 3 запроса. Я думаю, что вам нужно всего два вида: by_username и by_email. Это опечатка или я что-то упускаю? - person Marcello Nuccio; 19.08.2011
comment
Извините, изначально я прочитал вопрос как a OR b OR c, но на самом деле это был a AND b OR C, и редактирование для исправления было неполным. Главный урок: (1) иногда просто запросите несколько раз и присоединитесь к своему приложению, но (2) если это выйдет из-под контроля, похоже, вам все-таки нужен SQL. - person JasonSmith; 20.08.2011