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 se ejecuta un recorrido de Gremlin que devuelve una gran cantidad de resultados, Neptune los transmite al cliente en 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 recopilar 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 servidor, pero el cliente puede anular el tamaño del lote en función de cada solicitud mediante la opción de solicitud (llamada Tokens.ARGS_BATCH_SIZE en el controlador de Java o como opción predeterminada a nivel de controlador). batchSizeconnectionPool.resultIterationBatchSize
Como el servidor envía los resultados automáticamente, la contrapresión del lado del cliente se gestiona implícitamente mediante TCP y el control de flujo. WebSocket Si el cliente tarda en leer desde el socket, las escrituras del servidor acabarán por bloquearse 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 que se complete 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 memoria del lado del servidor.
Consumir los resultados de forma incremental
Para procesar los resultados a medida que van llegando, repita de forma perezosa utilizandohasNext()/next()o una versión equivalente APIs en lugar de recopilar todos los resultados en una lista. Se puede utilizar next(batchSize) para obtener los 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 le permite procesar los resultados de forma incremental a medida que se obtienen y devuelven datos adicionales. Los siguientes métodos bloquean hasta que todo el conjunto de resultados se recopila 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()Ve a:
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 la recopilación completa. Para procesar los resultados a medida que llegan, utilice los patrones de iteración diferida o por lotes que se muestran en los ejemplos anteriores.