Chargeur JSON
- JSON (JavaScript Object Notation) est un format de fichier standard ouvert et un format d'échange de données qui utilise un texte lisible pour stocker et transmettre des objets de données composés de paires attribut-valeur et de tableaux (ou d'autres valeurs sérialisables).
JSON Lines est un format de fichier où chaque ligne est une valeur JSON valide.
JSONLoader analyse les fichiers JSON à l'aide d'un motif jq spécifié et utilise le package jq Python. Pour une documentation détaillée sur la syntaxe jq, veuillez vous référer à la documentation Python pertinente.
from langchain_community.document_loaders import JSONLoader
import json
from pathlib import Path
from pprint import pprint
chemin_fichier = './exemple_donnees/discussion_facebook.json'
donnees = json.loads(Path(chemin_fichier).read_text())
pprint(donnees)
{'image': {'creation_timestamp': 1675549016, 'uri': 'image_de_la_discussion.jpg'},
'is_still_participant': True,
'joinable_mode': {'link': '', 'mode': 1},
'magic_words': [],
'messages': [{'content': 'Au revoir!',
'sender_name': 'Utilisateur 2',
'timestamp_ms': 1675597571851},
{'content': 'Oh, pas de soucis ! Au revoir',
'sender_name': 'Utilisateur 1',
'timestamp_ms': 1675597435669},
{'content': 'Non, désolé, c'était mon erreur, le bleu n'est pas '
'à vendre',
'sender_name': 'Utilisateur 2',
'timestamp_ms': 1675596277579},
{'content': 'Je pensais que vous vendiez le bleu !',
'sender_name': 'Utilisateur 1',
'timestamp_ms': 1675595140251},
{'content': 'Je ne suis pas intéressé par ce sac. Je suis '
'intéressé par le bleu !',
'sender_name': 'Utilisateur 1',
'timestamp_ms': 1675595109305},
{'content': 'Voici 129 $',
'sender_name': 'Utilisateur 2',
'timestamp_ms': 1675595068468},
{'photos': [{'creation_timestamp': 1675595059,
'uri': 'url_de_une_image.jpg'}],
'sender_name': 'Utilisateur 2',
'timestamp_ms': 1675595060730},
{'content': 'En ligne, c'est au moins 100 $',
'sender_name': 'Utilisateur 2',
'timestamp_ms': 1675595045152},
{'content': 'Combien en voulez-vous ?',
'sender_name': 'Utilisateur 1',
'timestamp_ms': 1675594799696},
{'content': 'Bonjour ! 50 $, c'est trop peu.',
'sender_name': 'Utilisateur 2',
'timestamp_ms': 1675577876645},
{'content': 'Salut ! Je suis intéressé par votre sac. Je propose '
'50 $. Faites-moi savoir si vous êtes intéressé. '
'Merci!',
'sender_name': 'Utilisateur 1',
'timestamp_ms': 1675549022673}],
'participants': [{'name': 'Utilisateur 1'}, {'name': 'Utilisateur 2'}],
'thread_path': 'boîte de réception/discussion Utilisateur 1 et Utilisateur 2',
'title': 'Discussion Utilisateur 1 et Utilisateur 2'}
Utilisation de JSONLoader
Supposons que nous voulons extraire les valeurs du champ content
sous la clé messages
dans les données JSON. L'utilisation de JSONLoader
peut facilement accomplir cette tâche.
loader = JSONLoader(
file_path='./example_data/facebook_chat.json',
jq_schema='.messages[].content')
data = loader.load()
pprint(data)
[Document(page_content='Au revoir!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1}),
Document(page_content='Oh non, pas de soucis! Au revoir', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2}),
Document(page_content='Non, désolé, c'était mon erreur, le bleu n'est pas à vendre', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3}),
Document(page_content='Je pensais que vous vendiez le bleu!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4}),
Document(page_content='Je ne suis pas intéressé par ce sac. Je suis intéressé par le bleu!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5}),
Document(page_content='Voici 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='En ligne, c'est au moins 100 $', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8}),
Document(page_content='Combien en voulez-vous?', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9}),
Document(page_content='Bonjour! 50 $, c'est trop peu.', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10}),
Document(page_content='Salut! Je suis intéressé par votre sac. Je propose 50 $. Faites-moi savoir si vous êtes intéressé. Merci!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11})]
Fichier JSON Lines
Si vous souhaitez charger des documents à partir d'un fichier JSON Lines, vous devez passer json_lines=True
et spécifier le jq_schema
pour extraire le page_content
à partir d'un objet JSON unique.
file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())
('{"sender_name": "Utilisateur 2", "timestamp_ms": 1675597571851, "content": "Au revoir !"}\n'
'{"sender_name": "Utilisateur 1", "timestamp_ms": 1675597435669, "content": "Oh pas de soucis ! Au revoir"}\n'
'{"sender_name": "Utilisateur 2", "timestamp_ms": 1675596277579, "content": "Non, désolé, c'était mon erreur, le bleu n'est pas à vendre"}\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='Au revoir !', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Document(page_content='Oh pas de soucis ! Au revoir', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Document(page_content="Non, désolé, c'était mon erreur, le bleu n'est pas à vendre", metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
Une autre option est de définir jq_schema='.'
et de fournir 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='Utilisateur 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Document(page_content='Utilisateur 1', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Document(page_content='Utilisateur 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
Extraction de métadonnées
En général, nous aimerions inclure les métadonnées d'un fichier JSON dans le document que nous créons à partir du contenu.
Ce qui suit montre comment utiliser JSONLoader
pour extraire des métadonnées.
Dans l'exemple précédent, nous n'avons pas collecté de métadonnées, mais nous avons réussi à spécifier dans le schéma l'emplacement à partir duquel la valeur page_content
peut être extraite directement.
.messages[].content
Dans l'exemple actuel, nous devons indiquer au chargeur d'itérer sur les enregistrements dans le champ messages
. Ensuite, le jq_schema
doit être :
.messages[]
Cela nous permet de transmettre les enregistrements (dictionnaires) à la "metadata_func" qui doit être implémentée. La "metadata_func" est responsable d'identifier quelles informations d'enregistrement doivent être incluses dans les métadonnées à stocker dans l'objet "Document" final.
De plus, nous devons maintenant spécifier explicitement le paramètre content_key
dans le chargeur pour extraire la valeur "page_content" à partir de quelle clé dans l'enregistrement.
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='Au revoir!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'Utilisateur 2', 'timestamp_ms': 1675597571851}),
Document(page_content='Oh, pas de soucis! Au revoir', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'Utilisateur 1', 'timestamp_ms': 1675597435669}),
Document(page_content='Non, je suis désolé, c'était mon erreur. Le bleu n'est pas à vendre', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3, 'sender_name': 'Utilisateur 2', 'timestamp_ms': 1675596277579}),
Document(page_content='Je pensais que vous vendiez le bleu!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4, 'sender_name': 'Utilisateur 1', 'timestamp_ms': 1675595140251}),
Document(page_content='Je ne suis pas intéressé par ce sac. Je m'intéresse au bleu!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5, 'sender_name': 'Utilisateur 1', 'timestamp_ms': 1675595109305}),
Document(page_content='Voici 129$', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6, 'sender_name': 'Utilisateur 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': 'Utilisateur 2', 'timestamp_ms': 1675595060730}),
Document(page_content='En ligne, c'est au moins 100$', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8, 'sender_name': 'Utilisateur 2', 'timestamp_ms': 1675595045152}),
Document(page_content='Combien en voulez-vous?', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9, 'sender_name': 'Utilisateur 1', 'timestamp_ms': 1675594799696}),
Document(page_content='Bonjour! 50$ c'est trop peu.', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10, 'sender_name': 'Utilisateur 2', 'timestamp_ms': 1675577876645}),
Document(page_content='Salut! Je suis intéressé par votre sac. Je propose 50$. Faites-moi savoir si cela vous intéresse. Merci!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11, 'sender_name': 'Utilisateur 1', 'timestamp_ms': 1675549022673})]
Ici, nous pouvons voir que ces fichiers contiennent déjà des métadonnées liées au contenu que nous avons extrait.
Fonction metadata_func
Comme indiqué ci-dessus, metadata_func
reçoit les métadonnées par défaut générées par JSONLoader
. Cela permet aux utilisateurs d'avoir un contrôle complet sur le format des métadonnées.
Par exemple, les métadonnées par défaut contiennent les clés source
et seq_num
. Cependant, les données JSON peuvent également contenir ces clés. Les utilisateurs peuvent utiliser metadata_func
pour renommer les clés par défaut et utiliser les clés des données JSON.
L'exemple suivant montre comment modifier la clé source
pour inclure uniquement les informations source du fichier liées au répertoire 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='Bye!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'Utilisateur 2', 'timestamp_ms': 1675597571851}),
Document(page_content='Oh, pas de soucis! Au revoir', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'Utilisateur 1', 'timestamp_ms': 1675597435669}),
...
...
... (contenu restant inchangé par souci de concision) ...
...
...
]
Structures JSON courantes pour l'utilisation de motifs jq
La liste suivante fournit des jq_schema
possibles que les utilisateurs peuvent utiliser comme référence pour extraire du contenu à partir de données JSON en fonction de la structure.
JSON -> [{"text": ...}, {"text": ...}, {"text": ...}]
jq_schema -> ".[].text"
JSON -> {"key": [{"text": ...}, {"text": ...}, {"text": ...}]}
jq_schema -> ".key[].text"
JSON -> ["...", "...", "..."]
jq_schema -> ".[]"