JSON-Lader
- JSON (JavaScript Object Notation) ist ein offenes Standard-Dateiformat und Dateninterchange-Format, das lesbarer Text verwendet, um Datenobjekte, die aus Attribut-Wert-Paaren und Arrays (oder anderen serialisierbaren Werten) bestehen, zu speichern und zu übertragen.
JSON Lines ist ein Dateiformat, bei dem jede Zeile einen gültigen JSON-Wert darstellt.
JSONLoader analysiert JSON-Dateien mithilfe eines angegebenen jq-Musters und verwendet das Python-Paket jq. Für ausführliche Dokumentation zur jq-Syntax siehe die entsprechende Python-Dokumentation.
from langchain_community.document_loaders import JSONLoader
import json
from pathlib import Path
from pprint import pprint
file_path = './beispiel_daten/facebook_chat.json'
data = json.loads(Path(file_path).read_text())
pprint(data)
{'image': {'creation_timestamp': 1675549016, 'uri': 'bild_des_chats.jpg'},
'is_still_participant': True,
'joinable_mode': {'link': '', 'mode': 1},
'magic_words': [],
'messages': [{'content': 'Tschüss!',
'sender_name': 'Benutzer 2',
'timestamp_ms': 1675597571851},
{'content': 'Ach, mach dir keine Sorgen! Tschüss',
'sender_name': 'Benutzer 1',
'timestamp_ms': 1675597435669},
{'content': 'Nein, tut mir leid, das war mein Fehler, der blaue ist nicht '
'zum Verkauf',
'sender_name': 'Benutzer 2',
'timestamp_ms': 1675596277579},
{'content': 'Ich dachte, du verkaufst den blauen!',
'sender_name': 'Benutzer 1',
'timestamp_ms': 1675595140251},
{'content': 'Ich bin nicht an dieser Tasche interessiert. Ich bin an der '
'blauen interessiert!',
'sender_name': 'Benutzer 1',
'timestamp_ms': 1675595109305},
{'content': 'Hier sind $129',
'sender_name': 'Benutzer 2',
'timestamp_ms': 1675595068468},
{'photos': [{'creation_timestamp': 1675595059,
'uri': 'url_des_einigen_bildes.jpg'}],
'sender_name': 'Benutzer 2',
'timestamp_ms': 1675595060730},
{'content': 'Online kostet es mindestens $100',
'sender_name': 'Benutzer 2',
'timestamp_ms': 1675595045152},
{'content': 'Wie viel willst du?',
'sender_name': 'Benutzer 1',
'timestamp_ms': 1675594799696},
{'content': 'Guten Morgen! $50 sind zu wenig.',
'sender_name': 'Benutzer 2',
'timestamp_ms': 1675577876645},
{'content': 'Hallo! Ich bin an deiner Tasche interessiert. Ich biete $50 an. Lass '
'mich wissen, ob du interessiert bist. Danke!',
'sender_name': 'Benutzer 1',
'timestamp_ms': 1675549022673}],
'participants': [{'name': 'Benutzer 1'}, {'name': 'Benutzer 2'}],
'thread_path': 'inbox/Benutzer 1 and Benutzer 2 chat',
'title': 'Benutzer 1 und Benutzer 2 chat'}
Verwendung von JSONLoader
Angenommen, wir möchten Werte aus dem Feld content
unter dem Schlüssel messages
in den JSON-Daten extrahieren. Mit Hilfe von JSONLoader
kann diese Aufgabe leicht erledigt werden.
loader = JSONLoader(
file_path='./example_data/facebook_chat.json',
jq_schema='.messages[].content')
data = loader.load()
pprint(data)
[Dokument(seiteninhalt='Tschüss!', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1}),
Dokument(seiteninhalt='Ach, keine Sorge! Tschüss', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2}),
Dokument(seiteninhalt='Entschuldigung, mein Fehler. Der blaue ist nicht zum Verkauf', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3}),
Dokument(seiteninhalt='Ich dachte, du verkaufst den blauen!', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4}),
Dokument(seiteninhalt='Ich bin nicht an dieser Tasche interessiert. Ich interessiere mich für den blauen!', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5}),
Dokument(seiteninhalt='Hier sind 129 Dollar', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6}),
Dokument(seiteninhalt='', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7}),
Dokument(seiteninhalt='Online sind es mindestens 100 Dollar', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8}),
Dokument(seiteninhalt='Wie viel möchtest du haben?', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9}),
Dokument(seiteninhalt='Guten Morgen! 50 Dollar sind zu wenig.', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10}),
Dokument(seiteninhalt='Hallo! Ich interessiere mich für deine Tasche. Ich biete 50 Dollar an. Lass mich wissen, wenn du interessiert bist. Danke!', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11})]
JSON-Lines-Datei
Wenn du Dokumente aus einer JSON-Lines-Datei laden möchtest, musst du json_lines=True
übergeben und das jq_schema
spezifizieren, um den page_content
aus einem einzelnen JSON-Objekt zu extrahieren.
file_path = './BeispielDaten/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())
('{"sender_name": "Benutzer 2", "timestamp_ms": 1675597571851, "content": "Tschüss!"}\n'
'{"sender_name": "Benutzer 1", "timestamp_ms": 1675597435669, "content": "Ach '
'mach dir keine Sorgen! Tschüss"}\n'
'{"sender_name": "Benutzer 2", "timestamp_ms": 1675596277579, "content": "Nein, Entschuldigung, mein Fehler. Der blaue ist nicht zum Verkauf"}\n')
loader = JSONLoader(
file_path='./BeispielDaten/facebook_chat_messages.jsonl',
jq_schema='.content',
json_lines=True)
data = loader.load()
pprint(data)
[Dokument(page_content='Tschüss!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Dokument(page_content='Ach mach dir keine Sorgen! Tschüss', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Dokument(page_content='Nein, Entschuldigung, mein Fehler. Der blaue ist nicht zum Verkauf', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
Eine andere Option ist es, jq_schema='.'
zu setzen und content_key
zu definieren:
loader = JSONLoader(
file_path='./BeispielDaten/facebook_chat_messages.jsonl',
jq_schema='.',
content_key='sender_name',
json_lines=True)
data = loader.load()
pprint(data)
[Dokument(page_content='Benutzer 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Dokument(page_content='Benutzer 1', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Dokument(page_content='Benutzer 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
Metadaten extrahieren
Normalerweise möchten wir die Metadaten aus einer JSON-Datei im Dokument einschließen, das wir aus dem Inhalt erstellen.
Im Folgenden wird gezeigt, wie man JSONLoader
verwendet, um Metadaten zu extrahieren.
Im vorherigen Beispiel haben wir keine Metadaten gesammelt, aber es ist uns gelungen, im Schema anzugeben, wo der Wert page_content
direkt extrahiert werden kann.
.messages[].content
Im aktuellen Beispiel müssen wir dem Loader mitteilen, dass er über die Datensätze im Feld messages
iterieren soll. Dann muss das jq_schema
lauten:
.messages[]
Dadurch können wir die Datensätze (Dictionaries) an die "metadata_func" übergeben, die implementiert werden muss. Die "metadata_func" ist dafür verantwortlich, zu identifizieren, welche Datensatzinformationen in den Metadaten enthalten sein sollen, die im finalen "Document"-Objekt gespeichert werden.
Zusätzlich müssen wir nun explizit den Parameter content_key
im Loader angeben, um den Wert "page_content" aus dem Schlüssel im Datensatz zu extrahieren.
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)
[Dokument(page_content='Tschüss!', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'Benutzer 2', 'timestamp_ms': 1675597571851}),
Dokument(page_content='Ach, keine Sorge! Tschüss', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'Benutzer 1', 'timestamp_ms':1675597435669}),
Dokument(page_content='Nein, es tut mir leid, es war mein Fehler. Der Blaue ist nicht zum Verkauf', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3, 'sender_name': 'Benutzer 2', 'timestamp_ms': 1675596277579}),
Dokument(page_content='Ich dachte, du wolltest den blauen kaufen!', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4, 'sender_name': 'Benutzer 1', 'timestamp_ms': 1675595140251}),
Dokument(page_content='Ich bin nicht an dieser Tasche interessiert. Ich möchte die blaue haben!', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5, 'sender_name': 'Benutzer 1', 'timestamp_ms': 1675595109305}),
Dokument(page_content='Hier sind $129', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6, 'sender_name': 'Benutzer 2', 'timestamp_ms': 1675595068468}),
Dokument(page_content='', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7, 'sender_name': 'Benutzer 2', 'timestamp_ms': 1675595060730}),
Dokument(page_content='Online kostet es mindestens $100', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8, 'sender_name': 'Benutzer 2', 'timestamp_ms': 1675595045152}),
Dokument(page_content='Wie viel möchtest du?', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9, 'sender_name': 'Benutzer 1', 'timestamp_ms': 1675594799696}),
Dokument(page_content='Guten Morgen! 50$ ist zu wenig.', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10, 'sender_name': 'Benutzer 2', 'timestamp_ms': 1675577876645}),
Dokument(page_content='Hi! Ich interessiere mich für deine Tasche. Ich biete 50$. Lass mich wissen, ob du interessiert bist. Danke!', metadaten={'quelle': '/Benutzer/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11, 'sender_name': 'Benutzer 1', 'timestamp_ms': 1675549022673})]
Hier können wir sehen, dass diese Dateien bereits Metadaten zum Inhalt enthalten, den wir extrahiert haben.
Funktion metadata_func
Wie oben gezeigt, erhält metadata_func
die Standardmetadaten, die von JSONLoader
generiert wurden. Dies ermöglicht es den Benutzern, die vollständige Kontrolle über das Format der Metadaten zu haben.
Beispielsweise enthält die Standardmetadaten die Schlüssel source
und seq_num
. Allerdings kann die JSON-Daten auch diese Schlüssel enthalten. Benutzer können metadata_func
verwenden, um die Standard-Schlüssel umzubenennen und die Schlüssel aus den JSON-Daten zu verwenden.
Das folgende Beispiel zeigt, wie man die source
ändert, um nur die Dateiquelleinformationen des Verzeichnisses langchain
einzuschließen.
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='Bye!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'Benutzer 2', 'timestamp_ms': 1675597571851}),
Document(page_content='Kein Problem! Tschüss', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'Benutzer 1', 'timestamp_ms': 1675597435669}),
...
...
... (restlicher Inhalt unverändert der Kürze halber) ...
...
...
]
Gemeinsame JSON-Strukturen für die Verwendung von jq-Mustern
Die folgende Liste bietet mögliche jq_schema
, die Benutzer als Referenz für das Extrahieren von Inhalten aus JSON-Daten basierend auf der Struktur verwenden können.
JSON -> [{"text": ...}, {"text": ...}, {"text": ...}]
jq_schema -> ".[].text"
JSON -> {"key": [{"text": ...}, {"text": ...}, {"text": ...}]}
jq_schema -> ".key[].text"
JSON -> ["...", "...", "..."]
jq_schema -> ".[]"