โปรแกรมโหลด 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': 'User 2',
                   'timestamp_ms': 1675597571851},
                  {'content': 'ไม่ต้องกังวล! ลาก่อน',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675597435669},
                  {'content': 'ไม่ใช่ ขอโทษ ผิดมั้ย คะ สีน้ำเงิน ไม่ขาย',
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675596277579},
                  {'content': 'คิดว่าคุณขายสีน้ำเงิน!',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675595140251},
                  {'content': 'ไม่สนใจกระเป๋านี้ สนใจกระเป๋าสีน้ำเงิน!',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675595109305},
                  {'content': 'นี่ มี $129',
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675595068468},
                  {'photos': [{'creation_timestamp': 1675595059,
                               'uri': 'url_of_some_picture.jpg'}],
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675595060730},
                  {'content': 'ออนไลน์คืออย่างน้อย $100',
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675595045152},
                  {'content': 'คุณต้องการเท่าไหร่?',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675594799696},
                  {'content': 'สวัสดีตอนเช้า! $50 ถูกเกินไป',
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675577876645},
                  {'content': 'สวัสดีค่ะ! ฉันสนใจกระเป๋าของคุณ ฉันมีข้อเสนอ $50 บาท แจ้งทราบฉันหากคุณสนใจ ขอบคุณ!',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675549022673}],
     'participants': [{'name': 'User 1'}, {'name': 'User 2'}],
     'thread_path': 'inbox/User 1 and User 2 chat',
     'title': 'User 1 and User 2 chat'}

การใช้ 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 Lines

หากคุณต้องการโหลดเอกสารจากไฟล์ JSON Lines คุณจำเป็นต้องใช้ json_lines=True และระบุ jq_schema เพื่อแยก page_content จากออบเจ็กต์ JSON แต่ละตัว

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})]

ดึงเมตาดาต้า

โดยปกติแล้ว เราต้องการรวมเมตาดาต้าจากไฟล์ JSON ในเอกสารที่เราสร้างจากเนื้อหา

ตัวอย่างต่อไปนี้มีการแสดงวิธีใช้ JSONLoader เพื่อดึงเอาเมตาดาต้า

ในตัวอย่างก่อนหน้านี้ เราไม่ได้เก็บเมตาดาต้า แต่สามารถระบุในแผนภาพสกีม่าถึงตำแหน่งที่ค่า page_content สามารถถูกดึงออกโดยตรง

.messages[].content

ในตัวอย่างปัจจุบัน เราต้องบอกโหลดเดอร์ที่จะวนลูปผ่านระเบียบในฟิลด์ messages จากนั้น jq_schema ต้องเป็น:

.messages[]

นี้ช่วยให้เราสามารถส่งระเบียบ (พจนานุกรม) ไปยัง "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='./example_data/facebook_chat.json',
    jq_schema='.messages[]',
    content_key="content",
    metadata_func=metadata_func
)

data = loader.load()
pprint(data)
[เอกสาร(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}),
     เอกสาร(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}),
     เอกสาร(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}),
     เอกสาร(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}),
     เอกสาร(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}),
     เอกสาร(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}),
     เอกสาร(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}),
     เอกสาร(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}),
     เอกสาร(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}),
     เอกสาร(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}),
     เอกสาร(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 รับข้อมูล metadata เริ่มต้นที่สร้างโดย JSONLoader นี้ช่วยให้ผู้ใช้มีควบคุมทั้งหมดในรูปแบบของ metadata

ยกตัวอย่างเช่น metadata เริ่มต้นมี key source และ seq_num อยู่ แต่ข้อมูล JSON ก็อาจมี key เหล่านี้อยู่ด้วย ผู้ใช้สามารถใช้ metadata_func เพื่อเปลี่ยนชื่อ key เริ่มต้นและใช้ key จากข้อมูล 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='บ๊าย!', 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='ไม่ต้องกังวล! บ๊าย', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'User 1', 'timestamp_ms': 1675597435669}),
     ...
     ...
     ... (ข้อมูลที่เหลือเปลี่ยนไม่เปลี่ยนเพียงเพื่อความกระชับ) ...
     ...
     ...
]

โครงสร้าง JSON ทั่วไปสำหรับการใช้รูปแบบ jq

รายการต่อไปนี้จะให้ตัวอย่าง jq_schema ที่ผู้ใช้สามารถใช้เป็นข้อมูลอ้างอิงในการดึงเนื้อหาจากข้อมูล JSON ขึ้นอยู่กับโครงสร้าง

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

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

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