Как запросить представление CouchDB с помощью составного ключа?

У меня есть представление Couchdb "record_by_date_product" со следующим определением:

function(doc) {
  emit([doc.logtime, doc.product_id], doc);
}

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

(logtime > fromdate & logtime < todate)  & product_id in (1,2,6)

Возможно ли это с этим видом?

Я также использую библиотеку Python CouchDB для доступа к CouchDB. Вот фрагмент кода:

server = couchdb.Server()
db = server['mydb']

results = db.view('_design/record_by_date_product/_view/record_by_date_product')

Эта страница http://packages.python.org/CouchDB/client.html#viewresults указывает, что мы можем использовать startkey и endkey. Но я не могу заставить его работать.

Спасибо


person Sreedhar Gundappa    schedule 13.01.2011    source источник


Ответы (3)


Кажется, я только что нашел точный ответ:

Создайте представление «sampleview», которое выглядит следующим образом:

{
   "records_by_date_product": {
       "map": "function(doc) {\n  emit([doc.prod_id, doc.logtime], doc);\n}"
   }
}

Допустим, параметры запроса:

prod_id in [1,3]
from_date = '2010-01-01 00:00:00'
to_date = '2010-01-02 00:00:00'

Затем вам нужно будет выполнить 2 отдельных запроса в одном и том же представлении:

http://localhost:5984/db/_design/sampleview/_view/records_by_date_product?startkey='\["1,2010-01-01%2000:00:00"\]'&endkey='\[1,"2010-01-02%2000:00:00"\]'

http://localhost:5984/db/_design/sampleview/_view/records_by_date_product?startkey='\[2,"2010-01-01%2000:00:00"\]'&endkey='\[2,"2010-01-02%2000:00:00"\]'

Обратите внимание, что каждый раз выполняется один и тот же запрос, за исключением того, что prod_id изменяется во втором запросе. Результаты должны быть сопоставлены позже. Надеюсь это поможет!

person Sreedhar Gundappa    schedule 14.01.2011
comment
Ты всего лишь один человек, верно? Вы только что ответили на свой вопрос и сказали: «Надеюсь, это поможет». В любом случае, это не сработает, потому что порядок ключей неправильный. Диапазон между [start_date, 1] и [end_date, 1] будет включать много вещей, которые вам не нужны, например все в диапазоне дат для продукта с идентификатором = 2. Это будет работать, если вы выдаете идентификатор продукта до даты. - person Brian Goldman; 14.01.2011
comment
Хехе! Я думал, что это поможет и другим! :) Вы правы, мне придется изменить порядок ключей, а затем запросить представление. Позвольте мне внести изменения в решение. Спасибо! - person Sreedhar Gundappa; 14.01.2011

Такой точный запрос невозможен. Как следует из документации, вы можете получить все в представлении в определенном ключевом диапазоне. Представления — это отсортированные структуры данных, поэтому все, что CouchDB делает для выполнения этого запроса, — это находит начальный ключ и начинает возвращать элементы, пока вы не нажмете конечный ключ.

Стратегия, которую вы должны использовать для этого запроса, зависит от характеристик самих данных. Самое главное, будете ли вы тратить много времени на отсеивание элементов, если будете использовать только первую часть ключа (logtime) и перебирать их в Python, отсеивая элементы, где product_id не будет совпадать? Если это так, вам следует подумать о написании другого представления, в основном отсортированного по product_id. Если нет, идите вперед и используйте подход от сорняков.

person Brian Goldman    schedule 13.01.2011

Как насчет этого решения:

  1. Я создаю представление для каждого продукта с logtime в качестве индекса.
  2. Получите доступ к каждому представлению, если это необходимо, и отфильтруйте результаты, используя диапазон - [от даты до даты]
  3. Сделайте 3 для каждого продукта во входных параметрах и сопоставьте результаты

У этого есть недостаток, заключающийся в том, что для каждого продукта нам придется создавать представление, и это похоже на ручной процесс.

Просто мысль! Дайте мне знать ваши взгляды.

person Sreedhar Gundappa    schedule 14.01.2011
comment
Это может быть проще. Просто измените порядок ключей, чтобы документы сортировались сначала по продукту, а затем по времени регистрации. Запросите одно и то же представление три раза, ища каждый продукт в нужном временном диапазоне. Это второе предложение в представленном мной ответе, поэтому, если оно вам нравится, отметьте его как принятое :) - person Brian Goldman; 14.01.2011
comment
Здравствуйте, как мне искать каждый продукт во временном диапазоне? Я думаю, что это именно тот вопрос, который я задал. Дело в том, что мы можем отправить в представление только дату или диапазон [startdate enddate]. Но мы не можем отправить одновременно и диапазон, и ID товара. Я рассматриваю возможность использования списков, которые принимают любое количество параметров запроса. Даст обновление. Спасибо! - person Sreedhar Gundappa; 14.01.2011
comment
Вы можете одновременно искать диапазон и идентификатор продукта. Представления CouchDB могут использовать составные ключи, и вы привели пример того, как их создать. Все, что вам нужно сделать, это изменить порядок вашего ключа, чтобы он был [doc.product_id, doc.logtime]. Чтобы запросить его, используйте startkeys и endkeys в том же формате из двух элементов, как указано в документации, на которую вы ссылаетесь. - person Brian Goldman; 14.01.2011
comment
Для записи вы можете использовать временные представления, а также возможно (при наличии разрешения) записывать представления в Couch, как и любые другие данные. - person holdenweb; 19.09.2017