Pemuat JSON

  • JSON (JavaScript Object Notation) adalah format berkas standar terbuka dan format pertukaran data yang menggunakan teks yang mudah dibaca untuk menyimpan dan mengirimkan objek data yang terdiri dari pasangan atribut-nilai dan larik (atau nilai yang dapat diserialkan) JSON Lines adalah format berkas di mana setiap baris adalah nilai JSON yang valid.

JSONLoader mem-parsing berkas JSON menggunakan pola jq yang ditentukan dan menggunakan paket jq Python. Untuk dokumentasi terperinci tentang sintaks jq, silakan merujuk ke dokumentasi Python terkait.

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': 'Selamat tinggal!',
                   'sender_name': 'Pengguna 2',
                   'timestamp_ms': 1675597571851},
                  {'content': 'Oh tidak masalah! Selamat tinggal',
                   'sender_name': 'Pengguna 1',
                   'timestamp_ms': 1675597435669},
                  {'content': 'Maaf, itu kesalahan saya, yang biru bukan untuk dijual',
                   'sender_name': 'Pengguna 2',
                   'timestamp_ms': 1675596277579},
                  {'content': 'Saya kira Anda menjual yang biru!',
                   'sender_name': 'Pengguna 1',
                   'timestamp_ms': 1675595140251},
                  {'content': 'Saya tidak tertarik pada tas ini. Saya tertarik pada yang biru!',
                   'sender_name': 'Pengguna 1',
                   'timestamp_ms': 1675595109305},
                  {'content': 'Ini ada $129',
                   'sender_name': 'Pengguna 2',
                   'timestamp_ms': 1675595068468},
                  {'photos': [{'creation_timestamp': 1675595059,
                               'uri': 'url_of_some_picture.jpg'}],
                   'sender_name': 'Pengguna 2',
                   'timestamp_ms': 1675595060730},
                  {'content': 'Online minimal $100',
                   'sender_name': 'Pengguna 2',
                   'timestamp_ms': 1675595045152},
                  {'content': 'Berapa yang Anda inginkan?',
                   'sender_name': 'Pengguna 1',
                   'timestamp_ms': 1675594799696},
                  {'content': 'Selamat pagi! $50 terlalu rendah.',
                   'sender_name': 'Pengguna 2',
                   'timestamp_ms': 1675577876645},
                  {'content': 'Hi! Saya tertarik pada tas Anda. Saya menawarkan $50. Beritahu saya jika Anda tertarik. Terima kasih!',
                   'sender_name': 'Pengguna 1',
                   'timestamp_ms': 1675549022673}],
     'participants': [{'name': 'Pengguna 1'}, {'name': 'Pengguna 2'}],
     'thread_path': 'inbox/Pengguna 1 dan Pengguna 2 chat',
     'title': 'Pengguna 1 dan Pengguna 2 chat'}

Menggunakan JSONLoader

Misalkan kita ingin mengekstrak nilai dari bidang content di bawah kunci messages dalam data JSON. Dengan memanfaatkan JSONLoader dapat dengan mudah menyelesaikan tugas ini.

loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[].content')

data = loader.load()
pprint(data)
[Dokumen(isi_halaman='Sampai jumpa!', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1}),
 Dokumen(isi_halaman='Oh tidak masalah! Sampai jumpa', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2}),
 Dokumen(isi_halaman='Maaf, itu kesalahan saya, yang biru tidak dijual', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3}),
 Dokumen(isi_halaman='Saya pikir Anda menjual yang biru!', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4}),
 Dokumen(isi_halaman='Saya tidak tertarik dengan tas ini. Saya tertarik dengan yang biru!', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5}),
 Dokumen(isi_halaman='Ini $129', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6}),
 Dokumen(isi_halaman='', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7}),
 Dokumen(isi_halaman='Online minimal $100', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8}),
 Dokumen(isi_halaman='Berapa yang kamu inginkan?', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9}),
 Dokumen(isi_halaman='Selamat pagi! $50 terlalu rendah.', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10}),
 Dokumen(isi_halaman='Hai! Saya tertarik dengan tas Anda. Saya menawarkan $50. Beritahu saya jika Anda tertarik. Terima kasih!', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11})]

Berkas JSON Lines

Jika Anda ingin memuat dokumen dari berkas JSON Lines, Anda perlu menyertakan json_lines=True dan menentukan jq_schema untuk mengekstrak page_content dari satu objek JSON.

file_path = './contoh_data/pesan_chat_facebook.jsonl'
pprint(Path(file_path).read_text())
('{"sender_name": "Pengguna 2", "timestamp_ms": 1675597571851, "content": "Selamat tinggal!"}\n'
     '{"sender_name": "Pengguna 1", "timestamp_ms": 1675597435669, "content": "Oh tidak masalah! Selamat tinggal"}\n'
     '{"sender_name": "Pengguna 2", "timestamp_ms": 1675596277579, "content": "Maaf, itu kesalahan saya, yang biru bukan untuk dijual"}\n')
loader = JSONLoader(
    file_path='./contoh_data/pesan_chat_facebook.jsonl',
    jq_schema='.content',
    json_lines=True)

data = loader.load()
pprint(data)
[Dokumen(page_content='Selamat tinggal!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/contoh_data/pesan_chat_facebook.jsonl', 'seq_num': 1}),
     Dokumen(page_content='Oh tidak masalah! Selamat tinggal', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/contoh_data/pesan_chat_facebook.jsonl', 'seq_num': 2}),
     Dokumen(page_content='Maaf, itu kesalahan saya, yang biru bukan untuk dijual', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/contoh_data/pesan_chat_facebook.jsonl', 'seq_num': 3})]

Opsi lain adalah menetapkan jq_schema='.' dan memberikan content_key:

loader = JSONLoader(
    file_path='./contoh_data/pesan_chat_facebook.jsonl',
    jq_schema='.',
    content_key='sender_name',
    json_lines=True)

data = loader.load()
pprint(data)
[Dokumen(page_content='Pengguna 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/contoh_data/pesan_chat_facebook.jsonl', 'seq_num': 1}),
     Dokumen(page_content='Pengguna 1', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/contoh_data/pesan_chat_facebook.jsonl', 'seq_num': 2}),
     Dokumen(page_content='Pengguna 2', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/contoh_data/pesan_chat_facebook.jsonl', 'seq_num': 3})]

Mengekstrak Metadata

Biasanya, kita ingin menyertakan metadata dari file JSON dalam dokumen yang kita buat dari konten tersebut.

Berikut cara menggunakan JSONLoader untuk mengekstrak metadata.

Pada contoh sebelumnya, kita tidak mengumpulkan metadata, tapi berhasil menentukan dalam skema lokasi dari nilai page_content yang dapat diekstrak langsung.

.messages[].content

Pada contoh saat ini, kita perlu memberi tahu loader untuk mengiterasi melalui catatan dalam bidang messages. Kemudian, skema jq_schema harus menjadi:

.messages[]

Hal ini memungkinkan kita untuk melewatkan catatan (kamus) ke "metadata_func" yang harus diimplementasikan. "metadata_func" bertanggung jawab untuk mengidentifikasi informasi catatan mana yang harus disertakan dalam metadata yang akan disimpan dalam objek "Document" akhir.

Selain itu, sekarang kita harus secara eksplisit menentukan parameter content_key dalam loader untuk mengekstrak nilai "page_content" dari kunci mana dalam catatan.

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)
[Dokumen(page_content='Selamat tinggal!', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'User 2', 'timestamp_ms': 1675597571851}),
     Dokumen(page_content='Oh tidak masalah! Selamat tinggal', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'User 1', 'timestamp_ms': 1675597435669}),
     Dokumen(page_content='Bukan, maaf itu kesalahan saya. Yang biru tidak dijual', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3, 'sender_name': 'User 2', 'timestamp_ms': 1675596277579}),
     Dokumen(page_content='Saya pikir Anda sedang menjual yang biru!', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4, 'sender_name': 'User 1', 'timestamp_ms': 1675595140251}),
     Dokumen(page_content='Saya tidak tertarik dengan tas ini. Saya tertarik dengan yang biru!', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5, 'sender_name': 'User 1', 'timestamp_ms': 1675595109305}),
     Dokumen(page_content='Ini $129', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6, 'sender_name': 'User 2', 'timestamp_ms': 1675595068468}),
     Dokumen(page_content='', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7, 'sender_name': 'User 2', 'timestamp_ms': 1675595060730}),
     Dokumen(page_content='Online setidaknya $100', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8, 'sender_name': 'User 2', 'timestamp_ms': 1675595045152}),
     Dokumen(page_content='Berapa yang Anda inginkan?', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9, 'sender_name': 'User 1', 'timestamp_ms': 1675594799696}),
     Dokumen(page_content='Selamat pagi! $50 terlalu rendah.', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10, 'sender_name': 'User 2', 'timestamp_ms': 1675577876645}),
     Dokumen(page_content='Hi! Saya tertarik dengan tas Anda. Saya menawarkan $50. Beri tahu saya jika Anda tertarik. Terima kasih!', metadata={'sumber': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11, 'sender_name': 'User 1', 'timestamp_ms': 1675549022673})]

Di sini kita bisa melihat bahwa file-file ini sudah mengandung metadata yang terkait dengan konten yang kita ekstrak.

Fungsi metadata_func

Seperti yang ditunjukkan di atas, metadata_func menerima metadata default yang dihasilkan oleh JSONLoader. Ini memungkinkan pengguna untuk memiliki kontrol penuh atas format metadata.

Sebagai contoh, metadata default berisi kunci source dan seq_num. Namun, data JSON juga mungkin mengandung kunci-kunci ini. Pengguna dapat menggunakan metadata_func untuk mengganti nama kunci default dan menggunakan kunci-kunci dari data JSON.

Contoh berikut menunjukkan bagaimana memodifikasi source untuk hanya menyertakan informasi sumber file terkait dengan direktori 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)
[Dokumen(isi_halaman='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}),
     Dokumen(isi_halaman='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}),
     ...
     ...
     ... (konten tersisa tidak berubah karena kejelasan) ...
     ...
     ...
]

Struktur JSON Umum untuk Menggunakan Pola jq

Daftar berikut menyediakan skema jq_schema yang mungkin dapat digunakan pengguna sebagai referensi untuk mengekstrak konten dari data JSON berdasarkan strukturnya.

JSON        -> [{"text": ...}, {"text": ...}, {"text": ...}]
jq_schema   -> ".[].text"

JSON        -> {"key": [{"text": ...}, {"text": ...}, {"text": ...}]}
jq_schema   -> ".key[].text"

JSON        -> ["...", "...", "..."]
jq_schema   -> ".[]"