Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Transmite los resultados de las consultas con Gremlin
Cuando ejecutas un recorrido por Gremlin que arroja una gran cantidad de resultados, Neptune los envía al cliente por lotes a través de la conexión. WebSocket Neptune envía los lotes de resultados a medida que se producen, sin esperar a que el cliente solicite más. Esto puede resultar ventajoso si desea procesar los resultados a medida que los devuelve el servidor, pero requiere el uso de patrones de iteración diferidos para evitar almacenar todo el conjunto de resultados en la memoria.
Neptune envía los resultados en lotes de 64 por WebSocket fotograma de forma predeterminada. No puede cambiar este valor predeterminado del lado del servidor, pero el cliente puede anular el tamaño del lote para cada solicitud mediante la opción de solicitud (que se activa Tokens.ARGS_BATCH_SIZE en el batchSizeconnectionPool.resultIterationBatchSize
Para obtener más información sobre la configuración de los controladores batchSize en otros idiomas, consulte la sección de configuración de cada controlador en la documentación de controladores y variantes de Apache Gremlin. TinkerPop
Como el servidor envía los resultados automáticamente, la contrapresión del lado del cliente se gestiona de forma implícita mediante TCP y el control de flujo. WebSocket Si el cliente tarda en leer desde el socket, las escrituras del servidor acabarán bloqueándose hasta que el cliente se ponga al día.
importante
La transmisión es más eficaz con recorridos que pueden producir resultados de forma incremental. Los recorridos que incluyanorder(),, groupCount() group()dedup(), u otros pasos que requieran completar el recorrido completo antes de emitir los resultados harán que Neptune materialice todo el conjunto de resultados en la memoria antes de que comience la transmisión. En estos casos, el procesamiento por lotes sigue reduciendo la sobrecarga de serialización por cuadro, pero no reduce el uso de la memoria del servidor.
El consumo de resultados de forma incremental
Para procesar los resultados a medida que llegan, realiza iteraciones perezosas utilizandohasNext()/next()o API equivalentes en lugar de recopilar todos los resultados en una lista. Puede utilizarla next(batchSize) para obtener resultados en lotes a nivel de aplicación, lo que le permite realizar trabajos intermedios entre lotes mientras el servidor sigue produciendo resultados.
ejemplo Java (código de bytes GLV)
GraphTraversalSource g = traversal().withRemote(connection); int batchSize = 10; int batchNum = 0; var traversal = g.V().hasLabel("movie").values("title").limit(1000); while (traversal.hasNext()) { var batch = traversal.next(batchSize); batchNum++; for (var title : batch) { System.out.println(" " + title); } // Do other intermediary work here between batch calls System.out.println("Batch " + batchNum + " processing complete\n"); }
ejemplo Python
g = traversal().with_remote(connection) BATCH_SIZE = 10 batch_num = 0 t = g.V().has_label('movie').values('title').limit(1000) while t.has_next(): batch = t.next(BATCH_SIZE) batch_num += 1 for title in batch: print(f" {title}") # Do other intermediary work here between batch calls print(f"Batch {batch_num} processing complete\n")
ejemplo Go
// The Go driver does not support next(n), so batches are accumulated manually. g := gremlingo.Traversal_().WithRemote(connection) resultSet, err := g.V().HasLabel("movie").Values("title").Limit(1000).GetResultSet() if err != nil { log.Fatal(err) } batchSize := 10 batchNum := 0 for { var batch []interface{} for i := 0; i < batchSize; i++ { result, ok, err := resultSet.One() // returns (value, ok, error); ok is false when results are exhausted if err != nil { log.Fatal(err) } if !ok { break } batch = append(batch, result) } if len(batch) == 0 { break } batchNum++ for _, v := range batch { fmt.Printf(" %v\n", v) } // Do other intermediary work here between batch calls fmt.Printf("Batch %d processing complete\n\n", batchNum) }
ejemplo.NET
var g = Traversal().WithRemote(connection); var batchSize = 10; var batchNum = 0; var traversal = g.V().HasLabel("movie").Values<string>("title").Limit<string>(1000); while (traversal.HasNext()) { var batch = traversal.Next(batchSize); batchNum++; foreach (var title in batch) { Console.WriteLine($" {title}"); } // Do other intermediary work here between batch calls Console.WriteLine($"Batch {batchNum} processing complete\n"); }
ejemplo Node.js
// The Node.js driver does not support next(n), so batches are accumulated manually. const g = traversal().withRemote(connection); const batchSize = 10; let batchNum = 0; const t = g.V().hasLabel('movie').values('title').limit(1000); while (true) { const batch = []; for (let i = 0; i < batchSize; i++) { const result = await t.next(); if (result.done) break; batch.push(result.value); } if (batch.length === 0) break; batchNum++; for (const title of batch) { console.log(` ${title}`); } // Do other intermediary work here between batch calls console.log(`Batch ${batchNum} processing complete\n`); }
Consumo entusiasta frente a consumo incremental
La transmisión permite procesar los resultados de forma incremental a medida que se obtienen y devuelven datos adicionales. Los siguientes métodos se bloquean hasta que todo el conjunto de resultados se recopile en la memoria, lo que impide que la aplicación actúe en función de los resultados a medida que llegan:
Java:
toList()otoSet()Python:
toList()otoSet()Vaya:
ToList()ToSet(), oGetResultSet().GetAll().NET:
ToList()oPromise()Node.js:
toList()
nota
Los datos siguen fluyendo de forma incremental a través de la WebSocket conexión, incluso cuando se utilizan estos métodos. La diferencia es que su aplicación no puede procesar los resultados individuales hasta que se complete toda la recopilación. Para procesar los resultados a medida que llegan, utilice la iteración lenta o los patrones por lotes que se muestran en los ejemplos anteriores.