NDJSON a JSON
Convierte registros delimitados por saltos de línea en un array, e indica la línea que falla.
Nada de lo que pegues sale de tu navegador. La lista de permitidos de connect-src convierte eso en una garantía del navegador, no en una promesa. Compruébalo tú mismo
Convierte JSON delimitado por saltos de línea en un único array. Cada línea se parsea de forma independiente, y cualquier línea que falle se reporta con su número en vez de tirar abajo el archivo entero.
NDJSON es lo que sale de los pipelines de logs, de las exportaciones de BigQuery, de los archivos bulk de Elasticsearch y de las APIs en streaming, y es lo que provoca los errores «Extra data» y «unexpected non-whitespace character» cuando se parsea como un solo documento.
Qué es NDJSON
Un valor JSON completo por línea, separados por un salto de línea. Sin comas entre registros, sin array envolvente. Las líneas en blanco se ignoran. Las extensiones convencionales son .ndjson y .jsonl.
JSON Lines y NDJSON son en la práctica el mismo formato descrito por dos pequeñas especificaciones que coinciden en todo lo que importa. Algunas herramientas nombran una y otras la otra; un archivo escrito para cualquiera de las dos se lee correctamente con ambas.
Por qué existe
Tres ventajas reales, todas derivadas de que los registros sean independientes.
- Se puede transmitir en flujo
- Quien lo consume procesa un registro cada vez y nunca sostiene el archivo entero. Una exportación de 50 GB no es problema; un array JSON de 50 GB sí lo es.
- Se puede añadir al final
- Añadir un registro es una única escritura al final del archivo. Añadir a un array JSON significa reescribir el corchete de cierre, que no es añadir en absoluto.
- Sobrevive a la corrupción
- Una línea mal formada te cuesta un registro. Un byte mal formado en un array JSON te cuesta el archivo.
En qué dirección convertir
A un array cuando los datos van a un sitio que espera un solo documento: un navegador, el cuerpo de una petición, un archivo de configuración. A NDJSON cuando van a un pipeline, a un log, a un archivo de solo-añadir o a cualquier cosa que fluya. Arriba tienes las dos direcciones.
How to do this in code
Leer y escribir NDJSON en código.
py Python
La comprensión de lista lo sostiene todo en memoria. Itera el archivo directamente para procesarlo en flujo.
import json
# Read
with open('events.ndjson') as f:
records = [json.loads(line) for line in f if line.strip()]
# Write
with open('events.ndjson', 'w') as f:
for r in records:
f.write(json.dumps(r) + '\n')
# pandas knows the format
import pandas as pd
df = pd.read_json('events.ndjson', lines=True) sh jq
-s absorbe todas las entradas en un array; -c escribe un valor compacto por línea. Esas dos opciones son toda la conversión.
# NDJSON to an array
jq -s . events.ndjson > events.json
# An array to NDJSON
jq -c '.[]' events.json > events.ndjson
# Filter a huge NDJSON file without loading it all
jq -c 'select(.level == "error")' events.ndjson js Node
crlfDelay: Infinity hace que readline trate CRLF como un único salto, lo que importa en archivos escritos en Windows.
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';
const rl = createInterface({
input: createReadStream('events.ndjson'),
crlfDelay: Infinity,
});
for await (const line of rl) {
if (!line.trim()) continue;
const record = JSON.parse(line);
// one record at a time, constant memory
} Preguntas frecuentes
- ¿NDJSON es lo mismo que JSON Lines?
- A todos los efectos prácticos, sí. Son dos pequeñas especificaciones que coinciden en lo importante: un valor JSON por línea, UTF-8, separados por saltos de línea. Las extensiones .jsonl y .ndjson se usan indistintamente.
- ¿Puede un registro ocupar varias líneas?
- No. Ese es todo el sentido del formato: el salto de línea es el separador de registros, así que cada registro debe estar exactamente en una línea. Minifica cada registro antes de escribirlo.
- ¿Por qué mi archivo NDJSON no se parsea como JSON?
- Porque no es un documento JSON, son muchos. JavaScript reporta «Unexpected non-whitespace character after JSON» y Python reporta «Extra data». Ambos significan que el parser terminó un valor y encontró otro.