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

StackOverflow https://stackoverflow.com/questions/1180474

  •  19-09-2019
  •  | 
  •  

Вопрос

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

// a Customer has many Orders; show them together in one view:
function(doc) {
  if (doc.Type == "customer") {
    emit([doc._id, 0], doc);
  } else if (doc.Type == "order") {
    emit([doc.customer_id, 1], doc);
  }
}

Я знаю, что могу использовать следующий запрос, чтобы получить один customer и все связанные с этим Orders:

?startkey=["some_customer_id"]&endkey=["some_customer_id", 2]

Но теперь я связал свой запрос очень близко к моему коду просмотра.Есть ли ценность, которую я могу вложить туда, куда я вкладываю свой "2" чтобы более четко сказать: "Я хочу все привязан к этому Клиенту"?Я думаю, что я видел

?startkey=["some_customer_id"]&endkey=["some_customer_id", {}]

Но я не уверен, что {} является определенный для сортировки после все остальное.

Кредит для смленц для метода соединения.

Дополнительные разъяснения от Вики-страница CouchDB по сопоставлению:

Запрос startkey=["foo"]&endkey=["foo",{}] будет соответствовать большинству ключей массива с "foo" в первом элементе, например ["foo","bar"] и ["foo",["bar","baz"]].Однако это не будет соответствовать ["foo",{"an":"object"}]

Итак {} является поздно в порядке сортировки, но определенно не Последние.

Это было полезно?

Решение

Вместо того, чтобы пытаться найти величайший возможное значение для второй элемент в вашем ключе массива, я бы предложил вместо этого попытаться найти наименьший возможное значение, большее, чем Первый: ?startkey=["some_customer_id"]&endkey=["some_customer_id\u0000"]&inclusive_end=false.

Другие советы

У меня есть две мысли.

Используйте временные метки

Вместо использования простых 0 и 1 для их поведения при сопоставлении используйте временную метку о том, что запись была создана (при условии, что они являются частью записей) a la [doc._id, doc.created_at].Затем вы могли бы запросить свое представление с помощью startkey некоторой достаточно ранней даты (вероятно, сработала бы epoch) и endkey "now", например date +%s.Этот диапазон ключей всегда должен включать в себя все, и у него есть дополнительное преимущество сортировки по дате, что, вероятно, в любом случае является тем, что вы хотите.

или просто не беспокойтесь об этом

Вы могли бы просто проиндексировать по идентификатору customer_id и ничего больше.Это имело бы приятное преимущество в возможности запрашивать, используя только key=<customer_id>.Конечно, записи не будут сопоставлены, когда они вернутся, но является ли это проблемой для вашего приложения?Если вы не ожидаете получить обратно тонны записей, вероятно, было бы тривиально просто удалить запись клиента из списка, как только у вас будут данные, извлеченные вашим приложением.

Например, в ruby:

customer_records = records.delete_if { |record| record.type == "customer" }

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

CouchDB в основном написан на Erlang.Я не думаю, что был бы верхний предел для размеров кортежа составных строк / составных ключей, отличных от системных ресурсов (напримерключ такой длины, что он использовал всю доступную память).Пределы масштабируемости CouchDB неизвестны в соответствии с сайтом CouchDB.Я бы предположил, что вы могли бы продолжать добавлять поля в огромный составной первичный ключ, и единственное, что вас остановило бы, - это системные ресурсы или жесткие ограничения, такие как максимальные целочисленные размеры в целевой архитектуре.

Поскольку CouchDB хранит все, используя JSON, стандарт ECMAScript, вероятно, ограничен наибольшими числовыми значениями.Все числа в JavaScript хранятся в виде IEEE 754 double с плавающей запятой.Я полагаю, что 64-разрядный double может представлять значения от - 5e-324 до +1.7976931348623157e+ 308.

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

Это должно сработать:

?startkey=["some_customer_id"]&endkey=["some_customer_id", "\uFFFF"]

Сюда должно входить все, что начинается с символа меньше \uFFFF (все символы юникода)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top