Cargador de JSON
- JSON (Notación de Objetos de JavaScript) es un formato de archivo estándar y un formato de intercambio de datos que utiliza texto legible para almacenar y transmitir objetos de datos que consisten en pares de atributos y valores y arrays (u otros valores serializables).
JSON Lines es un formato de archivo donde cada línea es un valor JSON válido.
JSONLoader analiza archivos JSON utilizando un patrón jq especificado y utiliza el paquete jq de Python. Para obtener documentación detallada sobre la sintaxis jq, consulte la documentación relevante de Python.
from langchain_community.document_loaders import JSONLoader
import json
from pathlib import Path
from pprint import pprint
file_path = './example_data/facebook_chat.json'
data = json.loads(Path(file_path).read_text())
pprint(data)
{'image': {'creation_timestamp': 1675549016, 'uri': 'image_of_the_chat.jpg'},
'is_still_participant': True,
'joinable_mode': {'link': '', 'mode': 1},
'magic_words': [],
'messages': [{'content': '¡Adiós!',
'sender_name': 'Usuario 2',
'timestamp_ms': 1675597571851},
{'content': 'Oh, ¡no te preocupes! Adiós',
'sender_name': 'Usuario 1',
'timestamp_ms': 1675597435669},
{'content': 'No, lo siento, fue mi error, el azul no está '
'en venta',
'sender_name': 'Usuario 2',
'timestamp_ms': 1675596277579},
{'content': '¡Pensé que estabas vendiendo el azul!',
'sender_name': 'Usuario 1',
'timestamp_ms': 1675595140251},
{'content': '¡No me interesa esta bolsa! ¡Me interesa la bolsa '
'azul!',
'sender_name': 'Usuario 1',
'timestamp_ms': 1675595109305},
{'content': 'Aquí tienes $129',
'sender_name': 'Usuario 2',
'timestamp_ms': 1675595068468},
{'photos': [{'creation_timestamp': 1675595059,
'uri': 'url_de_alguna_imagen.jpg'}],
'sender_name': 'Usuario 2',
'timestamp_ms': 1675595060730},
{'content': 'En línea está al menos $100',
'sender_name': 'Usuario 2',
'timestamp_ms': 1675595045152},
{'content': '¿Cuánto quieres?',
'sender_name': 'Usuario 1',
'timestamp_ms': 1675594799696},
{'content': '¡Buenos días! $50 es demasiado poco.',
'sender_name': 'Usuario 2',
'timestamp_ms': 1675577876645},
{'content': '¡Hola! Estoy interesado en tu bolsa. Ofrezco $50. '
'Avísame si estás interesado. ¡Gracias!',
'sender_name': 'Usuario 1',
'timestamp_ms': 1675549022673}],
'participants': [{'name': 'Usuario 1'}, {'name': 'Usuario 2'}],
'thread_path': 'bandeja de entrada/Chat de Usuario 1 y Usuario 2',
'title': 'Chat de Usuario 1 y Usuario 2'}
Uso de JSONLoader
Supongamos que queremos extraer valores del campo content
bajo la clave messages
en los datos JSON. Utilizar JSONLoader
puede lograr fácilmente esta tarea.
loader = JSONLoader(
file_path='./example_data/facebook_chat.json',
jq_schema='.messages[].content')
data = loader.load()
pprint(data)
[Documento(contenido_de_la_página='¡Adiós!', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 1}),
Documento(contenido_de_la_página='¡Oh, no te preocupes! Adiós', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 2}),
Documento(contenido_de_la_página='No, lo siento, fue mi error, el azul no está en venta', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 3}),
Documento(contenido_de_la_página='¡Pensé que estabas vendiendo el azul!', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 4}),
Documento(contenido_de_la_página='No estoy interesado en esta bolsa. ¡Estoy interesado en la azul!', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 5}),
Documento(contenido_de_la_página='Aquí está $129', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 6}),
Documento(contenido_de_la_página='', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 7}),
Documento(contenido_de_la_página='En línea es al menos $100', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 8}),
Documento(contenido_de_la_página='¿Cuánto quieres?', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 9}),
Documento(contenido_de_la_página='¡Buenos días! $50 es demasiado bajo.', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 10}),
Documento(contenido_de_la_página='¡Hola! Estoy interesado en tu bolsa. Ofrezco $50. Avísame si estás interesado. ¡Gracias!', metadatos={'origen': '/Usuarios/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'núm_seq': 11})]
Archivo de líneas JSON
Si deseas cargar documentos desde un archivo de líneas JSON, necesitas pasar json_lines=True
y especificar el jq_schema
para extraer page_content
de un solo objeto JSON.
file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())
('{"sender_name": "Usuario 2", "timestamp_ms": 1675597571851, "content": "¡Adiós!"}\n'
'{"sender_name": "Usuario 1", "timestamp_ms": 1675597435669, "content": "Oh no '
'te preocupes! ¡Adiós"}\n'
'{"sender_name": "Usuario 2", "timestamp_ms": 1675596277579, "content": "No, lo siento, fue mi error, el azul no está en venta"}\n')
loader = JSONLoader(
file_path='./example_data/facebook_chat_messages.jsonl',
jq_schema='.content',
json_lines=True)
data = loader.load()
pprint(data)
[Document(page_content='¡Adiós!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Document(page_content='Oh no te preocupes! ¡Adiós', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Document(page_content='No, lo siento, fue mi error, el azul no está en venta', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
Otra opción es configurar jq_schema='.'
y proporcionar content_key
:
loader = JSONLoader(
file_path='./example_data/facebook_chat_messages.jsonl',
jq_schema='.',
content_key='sender_name',
json_lines=True)
data = loader.load()
pprint(data)
[Document(page_content='Usuario 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Document(page_content='Usuario 1', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Document(page_content='Usuario 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
Extracción de Metadatos
Por lo general, nos gustaría incluir los metadatos de un archivo JSON en el documento que creamos a partir del contenido.
A continuación se muestra cómo usar JSONLoader
para extraer metadatos.
En el ejemplo anterior, no recopilamos metadatos, pero logramos especificar en el esquema la ubicación desde la cual se puede extraer directamente el valor de page_content
.
.messages[].content
En el ejemplo actual, necesitamos indicar al cargador que iterar sobre los registros en el campo de messages
. Luego, el jq_schema
debe ser:
.messages[]
Esto nos permite pasar los registros (diccionarios) a la "metadata_func" que debe implementarse. La "metadata_func" es responsable de identificar qué información del registro debe incluirse en los metadatos que se almacenarán en el objeto "Document" final.
Además, ahora debemos especificar explícitamente el parámetro content_key
en el cargador para extraer el valor de "page_content" de qué clave en el registro.
def metadata_func(registro: dict, metadatos: dict) -> dict:
metadatos["nombre_remitente"] = registro.get("sender_name")
metadatos["timestamp_ms"] = registro.get("timestamp_ms")
return metadatos
cargador = JSONLoader(
file_path='./example_data/facebook_chat.json',
jq_schema='.messages[]',
content_key="content",
metadata_func=metadata_func
)
datos = cargador.load()
pprint(datos)
[Documento(contenido_pagina='¡Adiós!', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 1, 'nombre_emisor': 'Usuario 2', 'marca_tiempo_ms': 1675597571851}),
Documento(contenido_pagina='Oh, no te preocupes! Adiós', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 2, 'nombre_emisor': 'Usuario 1', 'marca_tiempo_ms': 1675597435669}),
Documento(contenido_pagina='No, lo siento, fue mi error. El azul no está en venta', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 3, 'nombre_emisor': 'Usuario 2', 'marca_tiempo_ms': 1675596277579}),
Documento(contenido_pagina='¡Pensé que estabas vendiendo el azul!', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 4, 'nombre_emisor': 'Usuario 1', 'marca_tiempo_ms': 1675595140251}),
Documento(contenido_pagina='¡No estoy interesado en esta bolsa. Estoy interesado en la azul!', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 5, 'nombre_emisor': 'Usuario 1', 'marca_tiempo_ms': 1675595109305}),
Documento(contenido_pagina='Aquí hay $129', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 6, 'nombre_emisor': 'Usuario 2', 'marca_tiempo_ms': 1675595068468}),
Documento(contenido_pagina='', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 7, 'nombre_emisor': 'Usuario 2', 'marca_tiempo_ms': 1675595060730}),
Documento(contenido_pagina='En línea, es al menos $100', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 8, 'nombre_emisor': 'Usuario 2', 'marca_tiempo_ms': 1675595045152}),
Documento(contenido_pagina='¿Cuánto quieres?', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 9, 'nombre_emisor': 'Usuario 1', 'marca_tiempo_ms': 1675594799696}),
Documento(contenido_pagina='¡Buenos días! $50 es muy poco', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 10, 'nombre_emisor': 'Usuario 2', 'marca_tiempo_ms': 1675577876645}),
Documento(contenido_pagina='¡Hola! Estoy interesado en tu bolso. Ofrezco $50. Avísame si estás interesado. ¡Gracias!', metadatos={'fuente': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'num_secuencia': 11, 'nombre_emisor': 'Usuario 1', 'marca_tiempo_ms': 1675549022673})]
Aquí podemos ver que estos archivos ya contienen metadatos relacionados con el contenido que extrajimos.
Función metadata_func
Como se muestra arriba, metadata_func
recibe los metadatos predeterminados generados por JSONLoader
. Esto permite a los usuarios tener un control completo sobre el formato de los metadatos.
Por ejemplo, los metadatos predeterminados contienen las claves source
y seq_num
. Sin embargo, los datos JSON también pueden contener estas claves. Los usuarios pueden usar metadata_func
para renombrar las claves predeterminadas y utilizar las claves de los datos JSON.
El siguiente ejemplo demuestra cómo modificar el source
para incluir solo información de origen de archivos relacionados con el directorio langchain
.
def metadata_func(record: dict, metadata: dict) -> dict:
metadata["sender_name"] = record.get("sender_name")
metadata["timestamp_ms"] = record.get("timestamp_ms")
if "source" in metadata:
source = metadata["source"].split("/")
source = source[source.index("langchain"):]
metadata["source"] = "/".join(source)
return metadata
loader = JSONLoader(
file_path='./example_data/facebook_chat.json',
jq_schema='.messages[]',
content_key="content",
metadata_func=metadata_func
)
data = loader.load()
pprint(data)
[Document(page_content='¡Adiós!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'Usuario 2', 'timestamp_ms': 1675597571851}),
Document(page_content='Oh no te preocupes! Adiós', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'Usuario 1', 'timestamp_ms': 1675597435669}),
...
...
... (contenido restante sin cambios por brevedad) ...
...
...
]
Estructuras JSON comunes para usar patrones jq
La siguiente lista proporciona posibles jq_schema
que los usuarios pueden usar como referencia para extraer contenido de datos JSON basados en la estructura.
JSON -> [{"text": ...}, {"text": ...}, {"text": ...}]
jq_schema -> ".[].text"
JSON -> {"key": [{"text": ...}, {"text": ...}, {"text": ...}]}
jq_schema -> ".key[].text"
JSON -> ["...", "...", "..."]
jq_schema -> ".[]"