بارگذاری کننده JSON
- JSON (JavaScript Object Notation) یک فرمت فایل استاندارد باز و یک فرمت تبادل داده است که از متن قابل خواندن برای ذخیره و انتقال اشیاء دادهای که از جفتهای ویژگی-مقدار و آرایهها (یا سایر مقادیر قابل سریالسازی) تشکیل شدهاند بهره میبرد.
JSON Lines یک فرمت فایل است که در آن هر خط یک مقدار JSON معتبر است.
JSONLoader فایلهای JSON را با استفاده از یک الگوی jq مشخص میکند و از بسته jq Python استفاده میکند. برای مستندات دقیق در مورد سینتکس jq، لطفاً به مستندات مربوط به 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': 'خداحافظ!',
'sender_name': 'کاربر 2',
'timestamp_ms': 1675597571851},
{'content': 'اوه نگران نباش! خداحافظ',
'sender_name': 'کاربر 1',
'timestamp_ms': 1675597435669},
{'content': 'نه، من متاسفم، اشتباه من بود، آبی برای فروش نیست',
'sender_name': 'کاربر 2',
'timestamp_ms': 1675596277579},
{'content': 'من فکر کردم شما داشتید آبی را میفروشید!',
'sender_name': 'کاربر 1',
'timestamp_ms': 1675595140251},
{'content': 'من به این کیف علاقهای ندارم. به آبی علاقهمندم!',
'sender_name': 'کاربر 1',
'timestamp_ms': 1675595109305},
{'content': 'اینجا $129 است',
'sender_name': 'کاربر 2',
'timestamp_ms': 1675595068468},
{'photos': [{'creation_timestamp': 1675595059,
'uri': 'آدرس_تصویر.jpg'}],
'sender_name': 'کاربر 2',
'timestamp_ms': 1675595060730},
{'content': 'آنلاین حداقل $100 است',
'sender_name': 'کاربر 2',
'timestamp_ms': 1675595045152},
{'content': 'چقدر میخواهید؟',
'sender_name': 'کاربر 1',
'timestamp_ms': 1675594799696},
{'content': 'صبح بخیر! $50 خیلی کم است.',
'sender_name': 'کاربر 2',
'timestamp_ms': 1675577876645},
{'content': 'سلام! من به کیف شما علاقه دارم. من $50 پیشنهاد میکنم. اگر علاقه دارید به من بگوید. ممنون!',
'sender_name': 'کاربر 1',
'timestamp_ms': 1675549022673}],
'participants': [{'name': 'کاربر 1'}, {'name': 'کاربر 2'}],
'thread_path': 'inbox/چت_کاربر 1 و کاربر 2',
'title': 'چت کاربر 1 و کاربر 2'}
استفاده از JSONLoader
فرض کنید ما میخواهیم مقادیر را از فیلد content
زیر کلید messages
در دادههای JSON استخراج کنیم. با استفاده از JSONLoader
به راحتی میتوانیم این کار را انجام دهیم.
loader = JSONLoader(
file_path='./example_data/facebook_chat.json',
jq_schema='.messages[].content')
data = loader.load()
pprint(data)
[Document(page_content='خداحافظ!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1}),
Document(page_content='اهی هیچ مشکلی نیست! خداحافظ', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2}),
Document(page_content='نه متاسفم اشتباه من بود، آبی برای فروش نیست', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3}),
Document(page_content='فکر میکردم شما آبی را میفروشید!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4}),
Document(page_content='من به این کیف علاقهای ندارم. من به آبی علاقهمندم!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5}),
Document(page_content='اینجا $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='آنلاین حداقل $100 هست', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8}),
Document(page_content='چقدر میخواهید؟', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9}),
Document(page_content='صبحبخیر! $50 کمه.', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10}),
Document(page_content='سلام! من به کیف شما علاقهمند هستم. $50 پیشنهاد میکنم. اگر علاقهمند هستید به من بگوید. متشکرم!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11})]
فایل خطوط JSON
اگر می خواهید اسناد را از یک فایل خطوط JSON بارگیری کنید، باید json_lines=True
را ارسال کرده و jq_schema
را مشخص کنید تا از یک شی JSON مستقل page_content
را استخراج کنید.
file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())
('{"sender_name": "User 2", "timestamp_ms": 1675597571851, "content": "خداحافظ!"}\n'
'{"sender_name": "User 1", "timestamp_ms": 1675597435669, "content": "اوه نه، نگران نباش! خداحافظ"}\n'
'{"sender_name": "User 2", "timestamp_ms": 1675596277579, "content": "نه، متاسفم اشتباه من بود، آبی برای فروش نیست"}\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='خداحافظ!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Document(page_content='اوه نه، نگران نباش! خداحافظ', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Document(page_content='نه، متاسفم اشتباه من بود، آبی برای فروش نیست', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
گزینه دیگر این است که jq_schema='.'
را تنظیم کرده و 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='User 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
Document(page_content='User 1', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
Document(page_content='User 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
استخراج اطلاعات فایل های Meta
معمولاً ما میخواهیم اطلاعات فایل JSON را در سندی که از محتوا ایجاد میکنیم، اضافه کنیم.
در زیر، نحوه استفاده از JSONLoader
برای استخراج اطلاعات Meta نمایش داده شده است.
در مثال قبل، ما اطلاعات Meta را جمعآوری نکردیم، اما توانستیم در طرح، مکانی را که میتوان به صورت مستقیم مقدار page_content
را استخراج کرد، مشخص کنیم.
.messages[].content
در مثال فعلی، ما باید به بارگیر بگوییم که باید بر روی رکوردها در فیلد messages
حلقه بزند. سپس، jq_schema
باید به این شکل باشد:
.messages[]
این کار به ما امکان میدهد تا رکوردها (فرهنگها) را به "metadata_func" که باید پیادهسازی شود، منتقل کنیم. "metadata_func" مسئول شناسایی اطلاعات رکوردی است که باید در متااطلاعات قرار گیرد تا در نهایت در "Document" نهایی ذخیره شود.
به علاوه، ما اکنون باید به صورت صریح پارامتر content_key
را در بارگیری مشخص کنیم تا مقدار "page_content" را از کدام کلید در رکورد استخراج کنیم.
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='./مثال_داده/چت_فیسبوک.json',
jq_schema='.messages[]',
content_key="content",
metadata_func=metadata_func
)
data = loader.load()
pprint(data)
[Document(page_content='خداحافظ!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'کاربر 2', 'timestamp_ms': 1675597571851}),
Document(page_content='اوه نگران نباش! خداحافظ', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'کاربر 1', 'timestamp_ms': 1675597435669}),
Document(page_content='نه، متاسفم اشتباه من بود. آبی برای فروش نیست', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3, 'sender_name': 'کاربر 2', 'timestamp_ms': 1675596277579}),
Document(page_content='فکر کردم شما آبی را میفروشید!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4, 'sender_name': 'کاربر 1', 'timestamp_ms': 1675595140251}),
Document(page_content='من به این کیف علاقهای ندارم. من به آبی علاقهمندم!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5, 'sender_name': 'کاربر 1', 'timestamp_ms': 1675595109305}),
Document(page_content='اینجا 129 دلار است', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6, 'sender_name': 'کاربر 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': 'کاربر 2', 'timestamp_ms': 1675595060730}),
Document(page_content='آنلاین حداقل 100 دلار است', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8, 'sender_name': 'کاربر 2', 'timestamp_ms': 1675595045152}),
Document(page_content='چه مقدار میخواهید؟', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9, 'sender_name': 'کاربر 1', 'timestamp_ms': 1675594799696}),
Document(page_content='صبح بخیر! 50 دلار خیلی کم است.', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10, 'sender_name': 'کاربر 2', 'timestamp_ms': 1675577876645}),
Document(page_content='سلام! به کیف شما علاقهمندم. میپیشنهاد میکنم 50 دلار. اگر علاقهمند هستید به من اطلاع دهید. متشکرم!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11, 'sender_name': 'کاربر 1', 'timestamp_ms': 1675549022673})]
اینجا میتوانیم ببینیم که این فایلها در حال حاضر شامل اطلاعات فرادادهای مرتبط با محتوایی است که استخراج کردیم.
تابع metadata_func
همانطور که در بالا نشان داده شده است، تابع metadata_func
، متادیتا پیشفرض تولید شده توسط JSONLoader
را دریافت میکند. این کار به کاربران امکان کنترل کامل بر روی فرمت متادیتا را میدهد.
به عنوان مثال، متادیتای پیشفرض شامل کلیدهای source
و seq_num
است. با این حال، دادههای JSON همچنین ممکن است این کلیدها را داشته باشند. کاربران میتوانند از metadata_func
برای تغییر نام کلیدهای پیشفرض استفاده کرده و از کلیدهای موجود در دادههای JSON استفاده نمایند.
مثال زیر نشان میدهد چگونه source
را به گونهای تغییر دهیم که تنها اطلاعات منبع فایل مرتبط با دایرکتوری 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': 'User 2', 'timestamp_ms': 1675597571851}),
Document(page_content='Oh no worries! Bye', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'User 1', 'timestamp_ms': 1675597435669}),
...
...
... (remaining content unchanged for brevity) ...
...
...
]
ساختارهای متداول JSON برای استفاده از الگوهای jq
لیست زیر، الگوهای jq_schema
ممکن را که کاربران میتوانند به عنوان مرجع برای استخراج محتوا از دادههای JSON بر اساس ساختار، ارائه میدهد.
JSON -> [{"text": ...}, {"text": ...}, {"text": ...}]
jq_schema -> ".[].text"
JSON -> {"key": [{"text": ...}, {"text": ...}, {"text": ...}]}
jq_schema -> ".key[].text"
JSON -> ["...", "...", "..."]
jq_schema -> ".[]"