2016-01-04 5 views
0

я получил представление, как это:Составной ключ в выполнение запроса couchbase 4.0

function (doc, meta) { 
    if(doc.type){ 
    var id = doc.id ? doc.id: ""; 
    var company = doc.company ? doc.company: ""; 
    var store = doc.store ? doc.store: ""; 

    emit([doc.type, id, company, store]); 
    } 
} 

И документы, которые содержат тип и комбинацию других 3-х полей, в зависимости от типа. Я хочу запросить в общем с помощью этой точки зрения с помощью следующей функции:

def find_by_type_pageing_by_id_company_store(self, format_function=None, page=None, rows=None, recent=None, type=None, id="", company="", store="", include_docs=True): 

    if not type: 
     logger.error("No Type Provided in find by type query") 
     raise exceptions.InvalidQueryParams("No Type Provided in find by type query") 

    view = VIEW_BY_TYPE_VIN_COMPANY_STORE 

    cb = self.get_cb_bucket() 

    query = Query() 

    # 'recent' and 'rows' are equivalent and will be unified to 'limit' here 
    if recent and rows: 
     raise exceptions.InvalidQueryParams(detail="Query may not contain both 'recent' and 'rows'") 
    limit = rows or recent 

    if limit: 
     try: 
      rows_per_page = int(limit) 
     except ValueError: 
      raise exceptions.InvalidQueryParams(detail="Query params 'recent' and 'rows' have to be integers") 

     if rows_per_page > settings.PAGINATION_MAX_ROWS_LIMIT: 
      raise exceptions.InvalidQueryParams(detail="Query params 'recent' and 'rows' may not exceed %s. " 
               "Use the additional param 'page=2', 'page=3', etc. to access " 
               "more objects" % settings.PAGINATION_MAX_ROWS_LIMIT) 
     try: 
      page = 1 if page is None else int(page) 
     except ValueError: 
      raise exceptions.InvalidQueryParams(detail="Query param 'page' has to be an integer") 

     skip = rows_per_page * (page - 1) 

     query.limit = rows_per_page 
     query.skip = skip 

    query.mapkey_range = [ 
     [type, id, company, workshop], 
     [type, id + query.STRING_RANGE_END, company + query.STRING_RANGE_END, store + query.STRING_RANGE_END] 
    ] 

    rows = cb.query(view['doc'], view['view'], include_docs=include_docs, query=query) 

    if format_function is None: 
     format_function = self.format_function_default 

    return_array = format_function(rows) 
    return return_array 

Он работает безотказно при запросе только для определенного типа, или типа и диапазона идентификаторов.

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

Я попытался с помощью:

query.mapkey_range = [ 
    ["Vehicle", "", "abc", ""] 
    ["Vehicle", q.STRING_RANGE_END, "abc", q.STRING_RANGE_END] 
] 

Я знаю, как-то порядок значений в составных ключевых вопросах, вот почему запрос для диапазона идентификаторов, вероятно, является успешным.

Но я не нашел подробного объяснения того, как этот порядок имеет значение и как обрабатывать этот прецедент.

Любая идея или намек на то, как справиться с этим? Спасибо заранее.

ответ

1

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

В вашем случае:

  • индекс содержит все Транспортные средства
  • все средства затем отсортированные по идентификатору
  • для каждого подобного идентификатора, Транспорт сортированы по компании
  • для каждого подобного идентификатора и компания, Транспортные средства затем сортируются по магазинам

Давайте рассмотрим пример из 4 автомобилей.Вот то, что индекс будет выглядеть так:

Vehicle,a,ACME,store100 
Vehicle,c,StackOverflow,store1001 
Vehicle,d,ACME,store100 
Vehicle,e,StackOverflow,store999 

Вот что происходит с запросом диапазона:

  • Вид двигатель находит первую строку> = к Клавишапуску из вашего диапазона
  • It затем находит последний, который < = к EndKey вашего диапазона
  • Он возвращает каждую строку между в массиве

Вы можете видеть, как, в зависимости от ид, это может привести к, казалось бы, плохие результаты: для [["Vehicle", "", "ACME", ""], ["Vehicle", RANGE_END, "ACME", RANGE_END]], вот что происходит:

  • строка 1 (a) определяется как наименьшая сопоставления Клавишапуска
  • строка 4 (e) не соответствует EndKey, потому что "Vehicle,e,StackOverflow,store999" больше "Vehicle,RANGE_END,ACME,RANGE_END" за счет третьего компонента
  • строка 3 (d) является верхним бо унд: Vehicle <= Vehicle, d <= RANGE_END, ACME <= ACME, store100 <= RANGE_END
  • поэтому грести 1-3 возвращаются, в том числе ряд 2 с «StackOverflow»

TL/DR: Заказ в вопросах испускают, вы не можете запросить с редкими «джокеров» в левую часть составного ключа.

Измените функцию карты на emit(doc.type, doc.company, doc.store, id) (наиболее общий для младшего общего атрибута), и она должна работать нормально после того, как вы соответствующим образом переработаете свой запрос.

Вот ссылка с дока объясняющего составных ключей и диапазоны датами: Partial Selection With Compound Keys

1

У вас есть два варианта запроса документов по переменному числу/порядка полей:

  1. Использовать многомерное (ака. пространственный вид), который позволяет опустить части составного ключа в запросе. Вот пример использования такого вида: http://developer.couchbase.com/documentation/server/4.0/views/sv-example2.html
  2. Используйте N1QL, который позволяет вам фактически запрашивать любое количество полей динамически. Убедитесь, что вы добавили индексы для полей, которые собираетесь запросить, и используйте оператор EXPLAIN, чтобы проверить, что ваши запросы выполняются так, как вы ожидаете. Вот как вы используете N1QL в Python: http://developer.couchbase.com/documentation/server/4.0/sdks/python-2.0/n1ql-queries.html

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

 Смежные вопросы

  • Нет связанных вопросов^_^