2012-05-12 11 views
9

Estoy probando la nueva API de búsqueda de App Engine para Java y tengo el siguiente código que trata de añadir ~ 3000 documentos en un índice:cuotas sobre API de búsqueda de Google App Engine para Java

List<Document> documents = new ArrayList<Document>(); 
    for (FacebookAlbum album: user.listAllAlbums()) { 
     Document doc = Document.newBuilder() 
       .setId(album.getId()) 
       .addField(Field.newBuilder().setName("name").setText(album.getFullName())) 
       .addField(Field.newBuilder().setName("albumId").setText(album.getAlbumId())) 
       .addField(Field.newBuilder().setName("createdTime").setDate(Field.date(album.getCreatedTime()))) 
       .addField(Field.newBuilder().setName("updatedTime").setDate(Field.date(album.getUpdatedTime()))) 
       .build(); 
     documents.add(doc); 
    }  

    try { 
     // Add all the documents. 
     getIndex(facebookId).add(documents); 
    } catch (AddException e) { 
     if (StatusCode.TRANSIENT_ERROR.equals(e.getOperationResult().getCode())) { 
      // retry adding document 
     } 
    } 

Sin embargo, estoy consiguiendo la siguiente excepción:

Uncaught exception from servlet 
java.lang.IllegalArgumentException: number of documents, 3433, exceeds maximum 200 
at com.google.appengine.api.search.IndexImpl.addAsync(IndexImpl.java:196) 
at com.google.appengine.api.search.IndexImpl.add(IndexImpl.java:380) 
at photomemories.buildIndexServlet.doGet(buildIndexServlet.java:47) 

¿Hay una cuota en el número de documentos que puedo insertar con una llamada de agregar establecida en 200?

Si trato de insertar un documento a la vez en el índice con el siguiente código:

for (FacebookAlbum album: user.listAllAlbums()) { 
     Document doc = Document.newBuilder() 
       .setId(album.getId()) 
       .addField(Field.newBuilder().setName("name").setText(album.getFullName())) 
       .addField(Field.newBuilder().setName("albumId").setText(album.getAlbumId())) 
       .addField(Field.newBuilder().setName("createdTime").setDate(Field.date(album.getCreatedTime()))) 
       .addField(Field.newBuilder().setName("updatedTime").setDate(Field.date(album.getUpdatedTime()))) 
       .build(); 

     try { 
      // Add the document. 
      getIndex(facebookId).add(doc); 
     } catch (AddException e) { 
      if (StatusCode.TRANSIENT_ERROR.equals(e.getOperationResult().getCode())) { 
       // retry adding document 
      } 
     } 

    }  

estoy recibiendo la siguiente excepción:

com.google.apphosting.api.ApiProxy$OverQuotaException: The API call search.IndexDocument() required more quota than is available. 
at com.google.apphosting.runtime.ApiProxyImpl$AsyncApiFuture.success(ApiProxyImpl.java:479) 
at com.google.apphosting.runtime.ApiProxyImpl$AsyncApiFuture.success(ApiProxyImpl.java:382) 
at com.google.net.rpc3.client.RpcStub$RpcCallbackDispatcher$1.runInContext(RpcStub.java:786) 
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:455) 

pensé que la cuota de la API las llamadas fueron 20k/día (ver aquí: https://developers.google.com/appengine/docs/java/search/overview#Quotas).

¿Alguna idea de lo que está pasando?

Respuesta

8

Hay algunas cosas que suceden aquí. Lo que es más importante, y esto es algo que se aclarará en la documentación muy pronto, la cuota de la API de búsqueda también representa la cantidad de documentos que se agregan/actualizan. Por lo tanto, una sola llamada Agregar que inserta 10 documentos reducirá su cuota diaria de API de búsqueda por 10.

Sí, la cantidad máxima de documentos que pueden indizarse en una sola llamada es de 200. Sin embargo, en esta etapa hay también una cuota de ráfaga a corto plazo implementada que lo limita a aproximadamente 100 llamadas de API por minuto.

Todo lo anterior significa que, por ahora al menos, es más seguro no agregar más de 100 documentos por solicitud de Agregar. Hacerlo a través de Task Queue recomendado por Shay también es una muy buena idea.

+0

Gracias Peter! Agregar ~ 3k documentos se logró llamando a agregar con un documento a la vez y teniendo una cola de tareas con un límite de velocidad de 2/s - la tasa de la cola predeterminada (5/s) estaba llegando a la cuota de ráfaga. Entonces, efectivamente, el límite de velocidad de ráfaga es> = 120 llamadas API por minuto. –

+0

Pregunta: ¿Existe entonces un beneficio (¿más rápido?) Al agregar llamadas con muchos documentos frente a muchas llamadas para agregar con un documento a la vez? –

+0

Envasar varios documentos en una sola llamada es un poco más eficiente. –

3

Creo que (no puedo encontrar una validación) que hay un límite de cuota por minuto, debe indexar sus documentos mediante una cola para asegurarse de que los indexe gradualmente.

+0

¿Cómo ayudaría una cola? ¿Es el límite de velocidad por tarea o qué? –

+0

Exactamente. Limite la cola para evitar alcanzar el límite de cuota. Google tiene cuotas por minuto (¿por segundo?) En todo el lugar. –

Cuestiones relacionadas