Caricatore JSON
- JSON (JavaScript Object Notation) è un formato di file standard aperto e un formato di scambio dati che utilizza testo leggibile per memorizzare e trasmettere oggetti di dati composti da coppie attributo-valore e array (o altri valori serializzabili).
JSON Lines è un formato di file in cui ciascuna riga è un valore JSON valido.
JSONLoader analizza i file JSON utilizzando un modello jq specificato e utilizza il pacchetto jq Python. Per una documentazione dettagliata sulla sintassi jq, consultare la documentazione Python rilevante.
from langchain_community.document_loaders import JSONLoader
import json
from pathlib import Path
from pprint import pprint
file_path = './esempio_dati/chat_facebook.json'
data = json.loads(Path(file_path).read_text())
pprint(data)
{'image': {'creation_timestamp': 1675549016, 'uri': 'immagine_del_chat.jpg'},
'is_still_participant': True,
'joinable_mode': {'link': '', 'mode': 1},
'magic_words': [],
'messages': [{'content': 'Ciao!',
'sender_name': 'Utente 2',
'timestamp_ms': 1675597571851},
{'content': 'Non ti preoccupare! Ciao',
'sender_name': 'Utente 1',
'timestamp_ms': 1675597435669},
{'content': 'No, mi dispiace, è stato un mio errore, quello blu '
'non è in vendita',
'sender_name': 'Utente 2',
'timestamp_ms': 1675596277579},
{'content': 'Pensavo che stessi vendendo quello blu!',
'sender_name': 'Utente 1',
'timestamp_ms': 1675595140251},
{'content': 'Non sono interessato a questa borsa. Sono interessato '
'a quella blu!',
'sender_name': 'Utente 1',
'timestamp_ms': 1675595109305},
{'content': 'Ecco $129',
'sender_name': 'Utente 2',
'timestamp_ms': 1675595068468},
{'photos': [{'creation_timestamp': 1675595059,
'uri': 'url_di_una_foto.jpg'}],
'sender_name': 'Utente 2',
'timestamp_ms': 1675595060730},
{'content': 'Online costa almeno $100',
'sender_name': 'Utente 2',
'timestamp_ms': 1675595045152},
{'content': 'Quanto vuoi?',
'sender_name': 'Utente 1',
'timestamp_ms': 1675594799696},
{'content': 'Buongiorno! $50 è troppo poco.',
'sender_name': 'Utente 2',
'timestamp_ms': 1675577876645},
{'content': 'Ciao! Sono interessato alla tua borsa. Offro $50. '
'Fammi sapere se sei interessato. Grazie!',
'sender_name': 'Utente 1',
'timestamp_ms': 1675549022673}],
'participants': [{'name': 'Utente 1'}, {'name': 'Utente 2'}],
'thread_path': 'inbox/Chat tra Utente 1 e Utente 2',
'title': 'Chat tra Utente 1 e Utente 2'}
Usando JSONLoader
Supponiamo che vogliamo estrarre i valori dal campo content
sotto la chiave messages
nei dati JSON. Utilizzando JSONLoader
possiamo facilmente completare questo compito.
loader = JSONLoader(
file_path='./example_data/facebook_chat.json',
jq_schema='.messages[].content')
data = loader.load()
pprint(data)
[Document(page_content='Ciao!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1}),
Document(page_content='Oh tranquillo! Ciao', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2}),
Document(page_content='No, mi dispiace, è stato un mio errore, il blu non è in vendita', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3}),
Document(page_content='Pensavo stessi vendendo quello blu!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4}),
Document(page_content='Non sono interessato a questa borsa. Sono interessato a quella blu!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5}),
Document(page_content='Ecco $129', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6}),
Document(page_content='', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7}),
Document(page_content='Online è almeno $100', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8}),
Document(page_content='Quanto ne vuoi?', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9}),
Document(page_content='Buongiorno! $50 è troppo poco.', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10}),
Document(page_content='Ciao! Sono interessato alla tua borsa. Offro $50. Fammi sapere se sei interessato. Grazie!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11})]
File JSON Lines
Se vuoi caricare documenti da un file JSON Lines, devi passare json_lines=True
e specificare lo jq_schema
per estrarre page_content
da un singolo oggetto JSON.
file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())
('{"sender_name": "Utente 2", "timestamp_ms": 1675597571851, "content": "Arrivederci!"}\n'
'{"sender_name": "Utente 1", "timestamp_ms": 1675597435669, "content": "Oh non ti preoccupare! Arrivederci"}\n'
'{"sender_name": "Utente 2", "timestamp_ms": 1675596277579, "content": "No scusa è stato un mio errore, il blu non è in vendita"}\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='Arrivederci!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Document(page_content='Oh non ti preoccupare! Arrivederci', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Document(page_content='No scusa è stato un mio errore, il blu non è in vendita', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
Un'altra opzione è impostare jq_schema='.'
e fornire 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='Utente 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Document(page_content='Utente 1', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Document(page_content='Utente 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
Estrazione dei metadati
Di solito, vogliamo includere i metadati da un file JSON nel documento che creiamo dal contenuto.
Di seguito viene mostrato come utilizzare JSONLoader
per estrarre i metadati.
Nell'esempio precedente, non abbiamo raccolto i metadati, ma siamo riusciti a specificare nello schema la posizione da cui il valore page_content
può essere estratto direttamente.
.messages[].content
Nell'esempio attuale, dobbiamo dire al caricatore di iterare sui record nel campo messages
. Quindi, lo schema jq_schema
deve essere:
.messages[]
Questo ci consente di passare i record (dizionari) alla "metadata_func" che deve essere implementata. La "metadata_func" è responsabile per identificare quali informazioni del record devono essere incluse nei metadati da memorizzare nell'oggetto "Document" finale.
Inoltre, ora dobbiamo specificare esplicitamente il parametro content_key
nel caricatore per estrarre il valore "page_content" da quale chiave nel record.
def metadata_func(record: dict, metadata: dict) -> dict:
metadata["sender_name"] = record.get("sender_name")
metadata["timestamp_ms"] = record.get("timestamp_ms")
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='Ciao!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'Utente 2', 'timestamp_ms': 1675597571851}),
Document(page_content='Oh, nessun problema! Ciao', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'Utente 1', 'timestamp_ms': 1675597435669}),
Document(page_content='No, mi dispiace, è stato un mio errore. Quello blu non è in vendita', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3, 'sender_name': 'Utente 2', 'timestamp_ms': 1675596277579}),
Document(page_content='Pensavo stessi vendendo quello blu!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4, 'sender_name': 'Utente 1', 'timestamp_ms': 1675595140251}),
Document(page_content='Non sono interessato a questa borsa. Mi interessa quella blu!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5, 'sender_name': 'Utente 1', 'timestamp_ms': 1675595109305}),
Document(page_content='Ecco $129', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6, 'sender_name': 'Utente 2', 'timestamp_ms': 1675595068468}),
Document(page_content='', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7, 'sender_name': 'Utente 2', 'timestamp_ms': 1675595060730}),
Document(page_content='Online costa almeno $100', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8, 'sender_name': 'Utente 2', 'timestamp_ms': 1675595045152}),
Document(page_content='Quanto ne vuoi?', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9, 'sender_name': 'Utente 1', 'timestamp_ms': 1675594799696}),
Document(page_content='Buongiorno! $50 è troppo poco.', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10, 'sender_name': 'Utente 2', 'timestamp_ms': 1675577876645}),
Document(page_content='Ciao! Sono interessato alla tua borsa. Offro $50. Fammi sapere se sei interessato. Grazie!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11, 'sender_name': 'Utente 1', 'timestamp_ms': 1675549022673})]
Qui possiamo vedere che questi file contengono già metadati correlati al contenuto che abbiamo estratto.
Funzione metadata_func
Come mostrato sopra, metadata_func
riceve i metadati predefiniti generati da JSONLoader
. Questo consente agli utenti di avere pieno controllo sul formato dei metadati.
Ad esempio, i metadati predefiniti contengono le chiavi source
e seq_num
. Tuttavia, i dati JSON potrebbero già contenere queste chiavi. Gli utenti possono utilizzare metadata_func
per rinominare le chiavi predefinite e utilizzare le chiavi presenti nei dati JSON.
L'esempio seguente dimostra come modificare il source
per includere solo le informazioni sulla fonte del file relative alla directory 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)
[Documento(contenuto_pagina='Ciao!', metadati={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'Utente 2', 'timestamp_ms': 1675597571851}),
Documento(contenuto_pagina='Oh nessun problema! Ciao', metadati={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'Utente 1', 'timestamp_ms': 1675597435669}),
...
...
... (restante contenuto invariato per brevità) ...
...
...
]
Strutture JSON comuni per l'utilizzo dei modelli jq
L'elenco seguente fornisce possibili jq_schema
che gli utenti possono utilizzare come riferimento per estrarre contenuti dai dati JSON in base alla struttura.
JSON -> [{"text": ...}, {"text": ...}, {"text": ...}]
jq_schema -> ".[].text"
JSON -> {"key": [{"text": ...}, {"text": ...}, {"text": ...}]}
jq_schema -> ".key[].text"
JSON -> ["...", "...", "..."]
jq_schema -> ".[]"