Tabla de contenidos
- 19.1. Introducción al Document Service
- 19.1.1. Interfaz Zend_Cloud_DocumentService_Adapter
- 19.1.2. Opciones de adaptador soportadas
- 19.1.3. Conceptos básicos
- 19.1.4. Excepciones
- 19.1.5. Crear una colección
- 19.1.6. Eliminar una colección
- 19.1.7. Listar las colecciones disponibles
- 19.1.8. Insertar un documento
- 19.1.9. Reemplazar un documento
- 19.1.10. Actualizar un documento
- 19.1.11. Eliminar un documento
- 19.1.12. Obtener un documento
- 19.1.13. Consultar una colección
- 19.1.14. Crear una consulta
- 19.1.15. Acceder a los adaptadores concretos
- 19.2. Introducción al Queue Service
- 19.2.1. Instanciar y configurar los adaptadores de QueueService
- 19.2.2. Conceptos básicos
- 19.2.3. Excepciones
- 19.2.4. Crear una cola
- 19.2.5. Eliminar una cola
- 19.2.6. Listar colas
- 19.2.7. Establecer los metadatos de una cola
- 19.2.8. Obtener los metadatos de una cola
- 19.2.9. Enviar un mensaje
- 19.2.10. Recibir un mensaje
- 19.2.11. Eliminar un mensaje
- 19.2.12. Acceder a los adaptadores concretos
- 19.3. Introducción al StorageService
- 19.3.1. Adaptadores de StorageService
- 19.3.2. Conceptos básicos
- 19.3.3. Excepciones
- 19.3.4. Almacenar un elemento
- 19.3.5. Obtener un elemento
- 19.3.6. Eliminar un elemento
- 19.3.7. Copiar un elemento
- 19.3.8. Mover un elemento
- 19.3.9. Renombrar un elemento
- 19.3.10. Listar elementos
- 19.3.11. Obtener metadatos
- 19.3.12. Almacenar metadatos
- 19.3.13. Eliminar metadatos
- 19.3.14. Acceder a los adaptadores concretos
- 19.4. Zend_Cloud_Infrastructure
- 19.5. Zend_Cloud_Infrastructure_Adapter
Zend_Cloud_DocumentService abstrae las interfaces de todas las
principales bases de datos de documentos - tanto en la nube como desplegadas localmente -
de modo que los desarrolladores puedan acceder a su funcionalidad común a través de una
única API. En otras palabras, una aplicación puede hacer uso de estas bases de datos y
servicios sin preocuparse de cómo se desplegará la aplicación. El origen de datos puede
elegirse únicamente mediante cambios de configuración en el momento del despliegue.
Las bases de datos y servicios de documentos son cada vez más comunes en el desarrollo de aplicaciones. Estos orígenes de datos son algo diferentes de los orígenes de datos relacionales tradicionales, ya que evitan las relaciones complejas en favor del rendimiento, la escalabilidad y la flexibilidad. Ejemplos de servicios orientados a documentos incluyen Amazon SimpleDB y Azure Table Storage.
La API SimpleCloud ofrece cierta flexibilidad para características específicas del
proveedor mediante un array $options en la firma de cada método.
Algunos adaptadores requieren ciertas opciones que también deben añadirse al array
$options. Es una buena práctica obtener estas opciones de un
archivo de configuración para mantener la compatibilidad con todos los servicios y bases
de datos; las opciones no reconocidas simplemente se descartarán, lo que permite usar
diferentes servicios según el entorno.
Si se requieren más requisitos específicos del proveedor, el desarrollador debe extender
el adaptador específico de Zend_Cloud_DocumentService para
añadir soporte para dichas características. De este modo, las características específicas
del proveedor pueden invocarse en la aplicación haciendo referencia a las extensiones de
la API SimpleCloud en la subclase del adaptador Simple Cloud.
La interfaz Zend_Cloud_DocumentService_Adapter define los
métodos que implementa cada adaptador concreto de servicio de documentos. Los
siguientes adaptadores se distribuyen con la API SimpleCloud:
Para instanciar un adaptador de servicio de documentos, utilice el método estático
Zend_Cloud_DocumentService_Factory::getAdapter(), que
acepta un array de configuración o un objeto Zend_Config.
La clave document_adapter debe especificar el nombre de la
clase del adaptador concreto. También pueden pasarse en este parámetro de
configuración claves específicas del adaptador.
Ejemplo 19.1. Ejemplo: Uso del adaptador SimpleDB
$adapterClass = 'Zend_Cloud_DocumentService_Adapter_SimpleDb';
$documents = Zend_Cloud_DocumentService_Factory::getAdapter(array(
Zend_Cloud_DocumentService_Factory::DOCUMENT_ADAPTER_KEY => $adapterClass,
Zend_Cloud_DocumentService_Adapter_SimpleDb::AWS_ACCESS_KEY => $amazonKey,
Zend_Cloud_DocumentService_Adapter_SimpleDb::AWS_SECRET_KEY => $amazonSecret
));
Tabla 19.1. Opciones comunes de Zend_Cloud_DocumentService_Adapter
| Clave de opción | Descripción | Utilizada en | Requerida | Por defecto |
|---|---|---|---|---|
| document_class |
Clase a usar para representar los documentos devueltos. La clase
proporcionada debe extender
|
Constructor | No | Zend_Cloud_Document_Service_Document |
| documentset_class |
Clase a usar para representar colecciones de documentos,
|
Constructor | No | Zend_Cloud_DocumentService_DocumentSet |
Tabla 19.2. Opciones de Zend_Cloud_DocumentService_Adapter_SimpleDb
| Clave de opción | Descripción | Utilizada en | Requerida | Por defecto |
|---|---|---|---|---|
| query_class |
Clase a usar para crear y ensamblar consultas para este servicio de
documentos; |
Constructor | No | Zend_Cloud_DocumentService_Adapter_SimpleDb_Query |
| aws_accesskey | Su clave de acceso de Amazon AWS | Constructor | Sí | Ninguno |
| aws_secretkey | Su clave secreta de Amazon AWS | Constructor | Sí | Ninguno |
| http_adapter | Adaptador HTTP a usar en todas las operaciones de acceso | Constructor | No | Zend_Http_Client_Adapter_Socket |
| merge |
Si es un booleano true, todos los valores de atributos se fusionan. También puede especificar un array de pares clave, donde la clave es la clave del atributo a fusionar, y el valor indica si se debe fusionar o no; un valor booleano true fusionará la clave dada. Cualquier atributo no especificado en este array será reemplazado. |
updateDocument() |
No | True |
| return_documents |
Si es un booleano true, |
query() |
No | True |
Tabla 19.3. Opciones de Zend_Cloud_DocumentService_Adapter_WindowsAzure
| Clave de opción | Descripción | Utilizada en | Requerida | Por defecto |
|---|---|---|---|---|
| query_class |
Clase a usar para crear y ensamblar consultas para este servicio de
documentos; |
Constructor | No | Zend_Cloud_DocumentService_Adapter_WindowsAzure_Query |
| default_partition_key |
La clave de partición por defecto a usar si no se especifica ninguna en el identificador del documento. Windows Azure requiere un identificador de documento de dos partes, formado por una PartitionKey y una RowKey. La PartitionKey normalmente será común para los documentos de una única colección - y potencialmente incluso en toda su instancia de tabla. Como tal, este ajuste le permite especificar la PartitionKey por defecto a utilizar para todos los documentos. Si no se especifica, el adaptador utilizará por defecto el nombre de la colección como PartitionKey. |
Constructor, setDefaultPartitionKey()
|
Nombre de la colección a la que pertenece el documento | |
| storage_accountname | Nombre de cuenta de Windows Azure | Constructor | Sí | Ninguno |
| storage_accountkey | Clave de cuenta de Windows Azure | Constructor | Sí | Ninguno |
| storage_host |
Host de acceso de Windows Azure, el valor por defecto es
|
Constructor | No | table.core.windows.net |
| storage_proxy_host | Nombre de host del proxy | Constructor | No | Ninguno |
| storage_proxy_port | Puerto del proxy | Constructor | No | 8080 |
| storage_proxy_credentials | Credenciales del proxy | Constructor | No | Ninguno |
| HTTP Adapter | Adaptador HTTP a usar en todas las operaciones de acceso | Constructor | No | Ninguno |
| verify_etag |
Verifica el ETag en el documento de destino y realiza la operación solo si el ETag coincide con el valor esperado |
updateDocument(),
replaceDocument(),
deleteDocument()
|
No | False |
Cada servicio y base de datos orientados a documentos utiliza su propia terminología y construcciones en su API. La API SimpleCloud identifica y abstrae una serie de conceptos y operaciones comunes que se comparten entre los proveedores.
El almacenamiento de documentos consiste en varias colecciones, que son unidades de almacenamiento lógicas análogas a las tablas de bases de datos en el mundo SQL. Las colecciones contienen documentos, que son esencialmente un conjunto de pares clave-valor, junto con algunos metadatos específicos del motor de almacenamiento, y se identifican mediante un ID de documento único.
Cada documento tiene su propia estructura (conjunto de campos) que no necesariamente debe coincidir con la estructura de ningún otro documento, incluso dentro de la misma colección. De hecho, puede cambiar esta estructura después de que el documento haya sido creado.
Los documentos pueden recuperarse por ID o mediante una consulta a una colección.
Los documentos se representan mediante la clase
Zend_Cloud_DocumentService_Document. Tenga en cuenta que la
clase de documento no valida los ID y datos suministrados, y no impone la
compatibilidad con los requisitos de cada adaptador.
Se puede acceder a los campos del documento usando las claves como propiedades de objeto y como elementos de array.
La interfaz básica de Zend_Cloud_DocumentService_Document es
la siguiente:
/**
* ArrayAccess allows accessing fields by array key:
* $doc['fieldname']
*
* IteratorAggregate allows iterating over all fields:
* foreach ($document as $field => $value) {
* echo "$field: $value\n";
* }
*
* Countable provides a count of all fields:
* count($document)
*/
class Zend_Cloud_DocumentService_Document
implements ArrayAccess, IteratorAggregate, Countable
{
const KEY_FIELD = '_id';
/**
* $fields may be an array or an object implementing ArrayAccess.
* If no $id is provided, it will look for a field matching KEY_FIELD to
* use as the identifier.
*/
public function __construct($fields, $id = null);
public function setId($id);
public function getId();
public function getFields();
public function getField($name);
public function setField($name, $value);
/**
* These allow overloading, so you may access fields as if they were
* native properties of the document
*/
public function __get($name);
public function __set($name, $value);
/**
* Alternately, you can acces fields as if via native getters and
* setters:
* $document->setFoo($value); // set "Foo" field to value
* $value = $document->getFoo(); // get "Foo" field value
public function __call($name, $args);
}
![]() |
Identificadores de documentos en Windows Azure |
|---|---|
|
Windows Azure técnicamente requiere una combinación de dos campos para identificar
de forma única los documentos: la
La conclusión es que puede utilizar claves de tipo string si desea maximizar la
portabilidad de su aplicación. Solo tenga en cuenta que su registro contendrá unos
pocos campos adicionales para denotar la clave ( |
Ejemplo 19.2. Crear un documento
$document = new Zend_Cloud_DocumentService_Document(array(
'key1' => 'value1',
'key2' => 123,
'key3' => 'thirdvalue',
), "DocumentId");
$document->otherkey = 'some more data';
echo "key 1: " . $document->key1 . "\n"; // object notation
echo "key 2: " . $document['key2'] . "\n"; // array notation
Ejemplo 19.3. Explorar los datos del documento
$document = $documents->fetchDocument("mydata", $id);
echo "Document ID: " . $document->getID() . "\n";
foreach ($document->getFields() as $key => $value) {
echo "Field $key is $value\n";
}
Si ocurre algún error en el servicio de documentos, se lanza
Zend_Cloud_DocumentService_Exception. Si la excepción fue
causada por el controlador del servicio subyacente, puede usar el método
getClientException() para recuperar la excepción original.
Dado que los diferentes proveedores en la nube implementan diferentes conjuntos de
servicios, algunos controladores no implementan ciertas características. En este caso,
se lanza la excepción
Zend_Cloud_OperationNotAvailableException.
Se crea una nueva colección usando createCollection().
Si llama a createCollection() con un nombre de colección que
ya existe, el servicio no hará nada y dejará la colección existente sin modificar.
Una colección se elimina llamando a deleteCollection().
Eliminar una colección elimina automáticamente todos los documentos contenidos en esa colección.
![]() |
Nota |
|---|---|
Eliminar una colección puede llevar un tiempo considerable en algunos servicios. No puede volver a crear una colección con el mismo nombre hasta que la colección y todos sus documentos se hayan eliminado por completo. |
Eliminar una colección inexistente no tendrá ningún efecto.
Una lista de las colecciones existentes se devuelve mediante
listCollections(). Este método devuelve un array con todos
los nombres de las colecciones pertenecientes a la cuenta que especificó al crear el
adaptador.
Ejemplo 19.6. Listar colecciones
$list = $documents->listCollections();
foreach ($list as $collection) {
echo "My collection: $collection\n";
}
Para insertar un documento, necesita proporcionar un objeto
Zend_Cloud_DocumentService_Document o un array asociativo de
datos, así como la colección en la que lo está insertando.
Muchos proveedores requieren que proporcione un ID de documento junto con su
documento. Si usa un objeto Zend_Cloud_DocumentService_Document,
puede especificarlo pasando el identificador al constructor al instanciar el objeto.
Si usa un array asociativo, el nombre de la clave será específico del adaptador; por
ejemplo, en Azure, el ID está compuesto por la PartitionKey y la RowKey; en Amazon
SimpleDB, el ID es el ItemName; también puede especificar la clave en el campo
_id para una mayor portabilidad.
Como tal, la forma más sencilla y compatible de especificar la clave es usar un objeto Document.
Ejemplo 19.7. Insertar un documento
// Instantiating and creating the document
$document = new Zend_Cloud_DocumentService_Document(array(
'key1' => 'value1',
'key2' => 123,
'key3' => 'thirdvalue',
), "DocumentID");
// inserting into the "mydata" collection
$documents->insertDocument("mydata", $document);
Reemplazar un documento significa eliminar todos los datos del
documento asociados a una clave de documento en particular y sustituirlos por un nuevo
conjunto de datos. A diferencia de actualizar, esta operación
no fusiona los datos antiguos y nuevos, sino que reemplaza el documento en su
totalidad. La operación de reemplazo, al igual que
insertDocument(), acepta un documento
Zend_Cloud_DocumentService_Document o un array de pares
clave-valor que especifican los nombres y valores de los nuevos campos, y la colección
en la que existe el documento.
![]() |
Se requiere el ID del documento |
|---|---|
Para reemplazar el documento, se requiere el ID del documento. Al igual que al insertar un documento, si usa un array asociativo para describir el documento, necesitará proporcionar una clave específica del proveedor que indique el ID del documento. Como tal, la forma más compatible de reemplazar un documento entre proveedores es utilizar un objeto Document, como se muestra en los ejemplos. |
Ejemplo 19.8. Reemplazar un documento
$document = new Zend_Cloud_DocumentService_Document(array(
'key1' => 'value1',
'key2' => 123,
'key3' => 'thirdvalue',
), "DocumentID");
// Update the document as found in the "mydata" collection
$documents->replaceDocument("mydata", $document);
También puede usar un objeto Document existente, reasignar los campos y/o asignar
nuevos campos, y pasarlo al método replaceDocument():
$docment->key4 = '4th value';
// Update the document as found in the "mydata" collection
$documents->replaceDocument("mydata", $document);
Actualizar un documento cambia los pares clave/valor en un
documento existente. Esta operación no comparte la semántica de
reemplazo; los valores de las claves que no se especifican en
el conjunto de datos no se cambiarán. Debe proporcionar tanto una clave de documento
como datos, ya sea mediante un documento
Zend_Cloud_DocumentService_Document o un array, a este método.
Si la clave es null y se proporciona un objeto documento, se usa la clave del
documento.
Ejemplo 19.9. Actualizar un documento
// update one field
$documents->updateDocument("mydata", "DocumentID", array("key2" => "new value"));
// or with document; this could be a document already retrieved from the service
$document = new Zend_Cloud_DocumentService_Document(array(
'key1' => 'value1',
'key2' => 123,
'key3' => 'thirdvalue',
), "DocumentID");
$documents->updateDocument("mydata", null, $document);
// copy document to another ID
$documents->updateDocument("mydata", "AnotherDocumentID", $document);
Amazon SimpleDB admite campos multivaluados, por lo que las actualizaciones de datos se fusionarán con el valor de clave anterior en lugar de reemplazarlo. La opción merge debe contener un array de nombres de campos a fusionar. El array debe ser pares clave/valor, donde la clave corresponde a la clave del campo, y el valor un valor booleano que indica el estado de fusión (booleano true fusionaría; false no lo haría). Cualquier clave no especificada en la opción merge se reemplazará en lugar de fusionarse.
Ejemplo 19.10. Fusionar campos de documento
// key2 is overwritten, key3 is merged
$documents->updateDocument('mydata', 'DocumentID',
array('key2' => 'new value', 'key3' => 'additional value'),
array('merge' => array('key3' => true))
);
Un documento puede eliminarse pasando su clave a
deleteDocument(). Eliminar un documento inexistente no tiene
ningún efecto.
Puede obtener un documento específico especificando su clave.
fetchDocument() devuelve una instancia de
Zend_Cloud_DocumentService_Document.
Ejemplo 19.12. Obtener un documento
$document = $service->fetchDocument('collectionName', 'DocumentID');
echo "Document ID: " . var_export($document->getID(), 1) . "\n";
foreach ($document->getFields() as $key => $value) {
echo "Field $key is $value\n";
}
Para encontrar documentos en la colección que cumplan ciertos criterios, use el método
query(). Este método acepta ya sea una cadena que es una
consulta dependiente del adaptador y se pasa tal cual al adaptador concreto, o una
instancia de un objeto de consulta estructurada de
Zend_Cloud_DocumentService_Query. El valor de retorno es un
Zend_Cloud_DocumentService_DocumentSet, que contiene
instancias de Zend_Cloud_DocumentService_Document que
satisfacen la consulta. El objeto DocumentSet es iterable y contable.
Ejemplo 19.13. Consultar una colección usando una consulta de cadena
$docs = $documents->query(
"collectionName",
"RowKey eq 'rowkey2' or RowKey eq 'rowkey2'"
);
foreach ($docs as $doc) {
$id = $doc->getId();
echo "Found document with ID: "
. var_export($id, 1)
. "\n";
}
Si usa un objeto de consulta estructurada, normalmente lo obtendrá mediante el método
select(). Esto garantiza que el objeto de consulta sea
específico de su adaptador, lo que asegura que se ensamble en una sintaxis que su
adaptador entienda.
Ejemplo 19.14. Consultar una colección con una consulta estructurada
$query = $service->select();
$query->from('collectionName')
->where('year > ?', array(1945))
->limit(3);
$docs = $documents->query('collectionName', $query);
foreach ($docs as $doc) {
$id = $doc->getId();
echo "Found document with ID: "
. var_export($id, 1)
. "\n";
}
Las clases Zend_Cloud_DocumentService_Query no limitan qué
cláusulas de consulta pueden usarse, pero la cláusula debe estar soportada por el
adaptador concreto subyacente. Las cláusulas actualmente soportadas incluyen:
-
select()- define qué campos se devuelven en el resultado.![[Note]](images/note.png)
Nota Windows Azure ignora el argumento de esta cláusula y siempre devuelve el documento completo.
from()- define el nombre de la colección usada en la consulta.where()- define las condiciones de la consulta. Acepta tres parámetros: condición, array de argumentos para reemplazar los campos "?" en la condición, y un argumento de conjunción que debe ser "and" u "or", y que se usará para unir esta condición con condiciones anteriores. Pueden especificarse múltiples cláusulaswhere().whereId()- define la condición por ID de documento (clave). El documento coincidente debe tener la misma clave. El método acepta un argumento - el ID (clave) requerido.limit()- limita los datos devueltos al número especificado de documentos.-
order()- ordena los datos devueltos por el campo especificado. Acepta dos argumentos - el primero es el nombre del campo y el segundo es 'asc' o 'desc' que especifica la dirección de ordenación.![[Note]](images/note.png)
Nota Esta cláusula actualmente no está soportada por Windows Azure.
Para conveniencia del usuario, el método select()
instancia un objeto de consulta específico del adaptador, y establece la cláusula
SELECT para él.
Ejemplo 19.15. Crear una consulta estructurada
$query = $documents->select()
->from('collectionName')
->where('year > ?', array(1945))
->limit(3);
$docs = $documents->query('collectionName', $query);
foreach ($docs as $doc) {
$id = $doc->getId();
echo "Found document with ID: "
. var_export($id, 1)
. "\n";
}
En ocasiones es necesario recuperar el adaptador concreto para el servicio con el que
está trabajando la API Document. Esto puede lograrse usando el método
getAdapter().
![]() |
Nota |
|---|---|
Acceder al adaptador subyacente rompe la portabilidad entre servicios, por lo que debe reservarse solo para circunstancias excepcionales. |
Ejemplo 19.16. Usar adaptadores concretos
// Since SimpleCloud Document API doesn't support batch upload, use concrete adapter $amazonSdb = $documents->getAdapter(); $amazonSdb->batchPutAttributes($items, 'collectionName');