2009-07-24 29 views
5

estoy usando lo que parece ser un truco común para la creación de una vista conjunta:¿Cuál es el valor máximo para una clave compuesta de CouchDB?

// 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); 
    } 
} 

Sé que puedo utilizar la siguiente consulta para obtener una sola customer y todos los relacionados Order s:

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

Pero ahora he vinculado mi consulta muy con mi código de vista. ¿Hay algún valor que pueda poner donde puse mi "2" para decir más claramente, "Quiero todo vinculado a este cliente"? Creo que he visto

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

Pero no estoy seguro de que es {}cierta para ordenar después de todo lo demás.

Crédito a cmlenz para el método de unión.

más aclaraciones de la CouchDB wiki page on collation:

La consulta startkey=["foo"]&endkey=["foo",{}] coincidirá con la mayoría de las claves de matriz con "foo" en el primer elemento, como ["foo","bar"] y ["foo",["bar","baz"]]. Sin embargo, no coincidirá con ["foo",{"an":"object"}]

Así es {} finales en el orden de clasificación, pero definitivamente no es la última .

Respuesta

1

En lugar de tratar de encontrar el mayor valor posible para el segundo elemento en su clave de la matriz, sugeriría lugar tratando de encontrar el posible valor menos mayor que la primera : ?startkey=["some_customer_id"]&endkey=["some_customer_id\u0000"]&inclusive_end=false.

+0

Nota "inclusive_end" protege contra el caso ridículo en el que realmente tiene una clave del formulario "some_customer_id \ u0000", al no incluir documentos que coincidan con la "endkey" en el resultado. – user359996

0

CouchDB está escrito principalmente en Erlang. No creo que haya un límite superior para un tamaño de tupla de compuesto de cuerda/compuesto aparte de los recursos del sistema (por ejemplo, una clave siempre que use toda la memoria disponible). Los límites de la escalabilidad de CouchDB son desconocidos según el sitio CouchDB. Supongo que podría seguir agregando campos en una gran clave primaria compuesta y lo único que lo detendría son los recursos del sistema o los límites duros, como los tamaños máximos de enteros en la arquitectura de destino.

Dado que CouchDB almacena todo usando JSON, probablemente esté limitado a los valores numéricos más grandes según el estándar ECMAScript. Todos los números en JavaScript se almacenan como un doble punto flotante IEEE 754. Creo que el doble de 64 bits puede representar valores de - 5e-324 a + 1.7976931348623157e + 308.

+0

Quizás no fui lo suficientemente claro. La ID para ese cliente no cambia entre los valores mínimo y máximo. CouchDB, sin embargo, permite claves compuestas. Primero ordena por la primera entrada (constante aquí, e igual a "un_customer_id"), luego por la segunda (nulo para la tecla de inicio, 2 o {} para la tecla de finalización), y así sucesivamente. Me pregunto si (y por qué) {} es el valor máximo posible para una clave en el orden de CouchDB. –

+0

Creo que el problema está en el título de mi pregunta. Cambiaré el nombre para mayor claridad. –

+0

Oh, no vi que estuvieras hablando de teclas compuestas. Parece que hay pocas limitaciones en CouchDB. Dudo que haya un límite estricto en el tamaño de la tupla para la clave compuesta. Creo que los recursos del sistema se probarían para algunas operaciones de DB si creó una tabla con miles de campos y cientos de campos como parte del índice compuesto. –

0

Parece que sería bueno tener una característica donde endKey podría ser inclusivo en lugar de exclusivo.

+0

En realidad, "endkey" está incluido por defecto. Debe especificar "endkey_inclusive = false" para obtener un comportamiento exclusivo. – user359996

0

Esto debería hacer el truco:

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

Esto debe incluir cualquier cosa que comienza con un carácter menos de \ uFFFF (todos los caracteres Unicode)

+2

No lo creo. El artículo al que vinculó dice que todas las cadenas vienen antes de todas las matrices, que a su vez vienen antes de todos los hash. Entonces ["some_customer_id", "\ uFFFF"] es 'menos que' ["some_customer_id", {}]. –

+0

¿qué tal:?key = ["some_customer_id"] & include_docs = true – bogphanny

+0

Esta no es una consulta de base de datos relacional. La coma no es una conjunción implícita. Todas las claves emitidas para esta vista son matrices de dos elementos, por lo que su consulta no arrojará resultados. – user359996

2

que tengo dos pensamientos

Utiliza marcas de tiempo

En lugar de utilizar simples 0 y 1 por su comportamiento intercalación, utilice una marca de tiempo que se creó el registro (suponiendo que son parte de los registros) a la [doc._id, doc.created_at]. Entonces podría consultar su vista con una clave de inicio de una fecha suficientemente temprana (epoch probablemente funcionaría), y una tecla de final de "ahora", por ejemplo, date +%s. Ese rango clave siempre debe incluir todo, y tiene el beneficio adicional de ordenar por fecha, que es probablemente lo que quiere de todos modos.

o, simplemente no preocuparse por ello

Se podía por el índice de customer_id y nada más. Esto tendría la buena ventaja de poder consultar usando solo key=<customer_id>. Claro, los registros no se recopilarán cuando vuelvan, pero ¿es eso un problema para su aplicación? A menos que esté esperando toneladas de registros, probablemente sería trivial simplemente sacar el registro del cliente de la lista una vez que tenga los datos recuperados por su aplicación.

Por ejemplo, en rubí:

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

De todas formas, las marcas de tiempo es probablemente la respuesta más atractivo para su caso.

Cuestiones relacionadas