Trình tải JSON

  • JSON (JavaScript Object Notation) là một định dạng tệp mở và định dạng trao đổi dữ liệu sử dụng văn bản dễ đọc để lưu trữ và truyền tải các đối tượng dữ liệu bao gồm các cặp thuộc tính-giá trị và mảng (hoặc các giá trị có thể tuần tự hóa khác).

JSON Lines là một định dạng tệp mà mỗi dòng là một giá trị JSON hợp lệ.

JSONLoader phân tích cú pháp JSON sử dụng mẫu jq cụ thể và nó sử dụng gói jq trong Python. Để biết tài liệu chi tiết về cú pháp jq, vui lòng tham khảo tài liệu Python tương ứng.

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': 'Tạm biệt!',
                   'sender_name': 'Người dùng 2',
                   'timestamp_ms': 1675597571851},
                  {'content': 'Thôi không sao! Tạm biệt',
                   'sender_name': 'Người dùng 1',
                   'timestamp_ms': 1675597435669},
                  {'content': 'Không, tôi xin lỗi, đó là lỗi của tôi, cái màu xanh không '
                              'phải để bán',
                   'sender_name': 'Người dùng 2',
                   'timestamp_ms': 1675596277579},
                  {'content': 'Tôi nghĩ bạn đang bán cái màu xanh!',
                   'sender_name': 'Người dùng 1',
                   'timestamp_ms': 1675595140251},
                  {'content': 'Tôi không quan tâm tới chiếc túi này. Tôi quan tâm tới cái '
                              'màu xanh!',
                   'sender_name': 'Người dùng 1',
                   'timestamp_ms': 1675595109305},
                  {'content': 'Đây là $129',
                   'sender_name': 'Người dùng 2',
                   'timestamp_ms': 1675595068468},
                  {'photos': [{'creation_timestamp': 1675595059,
                               'uri': 'url_của_một_bức_ảnh.jpg'}],
                   'sender_name': 'Người dùng 2',
                   'timestamp_ms': 1675595060730},
                  {'content': 'Online ít nhất cũng $100',
                   'sender_name': 'Người dùng 2',
                   'timestamp_ms': 1675595045152},
                  {'content': 'Bạn muốn bao nhiêu?',
                   'sender_name': 'Người dùng 1',
                   'timestamp_ms': 1675594799696},
                  {'content': 'Buổi sáng tốt lành! $50 quá thấp.',
                   'sender_name': 'Người dùng 2',
                   'timestamp_ms': 1675577876645},
                  {'content': 'Chào! Tôi quan tâm tới chiếc túi của bạn. Tôi đề nghị $50. Hãy '
                              'cho tôi biết nếu bạn quan tâm. Cảm ơn!',
                   'sender_name': 'Người dùng 1',
                   'timestamp_ms': 1675549022673}],
     'participants': [{'name': 'Người dùng 1'}, {'name': 'Người dùng 2'}],
     'thread_path': 'inbox/Người dùng 1 và Người dùng 2 chat',
     'title': 'Người dùng 1 và Người dùng 2 chat'}

Sử dụng JSONLoader

Giả sử chúng ta muốn trích xuất các giá trị từ trường content dưới khóa messages trong dữ liệu JSON. Sử dụng JSONLoader có thể dễ dàng thực hiện công việc này.

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

data = loader.load()
pprint(data)
[Document(page_content='Tạm biệt!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1}),
     Document(page_content='Oh không sao đâu! Tạm biệt', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2}),
     Document(page_content='Không, tôi xin lỗi, đó là lỗi của tôi, cái màu xanh không bán', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3}),
     Document(page_content='Tôi nghĩ rằng bạn đang bán cái màu xanh!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4}),
     Document(page_content='Tôi không quan tâm cái túi này. Tôi quan tâm cái màu xanh!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5}),
     Document(page_content='Đây là $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='Online ít nhất là $100', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8}),
     Document(page_content='Bạn muốn bao nhiêu? ', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9}),
     Document(page_content='Chào buổi sáng! $50 là quá thấp.', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10}),
     Document(page_content='Chào! Tôi quan tâm đến cậu túi của bạn. Tôi đề nghị $50. Hãy cho tôi biết nếu bạn quan tâm. Cám ơn!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11})]

Tệp JSON Lines

Nếu bạn muốn tải tài liệu từ tệp JSON Lines, bạn cần chuyển json_lines=True và chỉ định jq_schema để trích xuất page_content từ một đối tượng JSON đơn.

file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())
('{"sender_name": "User 2", "timestamp_ms": 1675597571851, "content": "Tạm biệt!"}\n'
     '{"sender_name": "User 1", "timestamp_ms": 1675597435669, "content": "Ôi không sao '
     'cả! Tạm biệt"}\n'
     '{"sender_name": "User 2", "timestamp_ms": 1675596277579, "content": "Không, tôi xin '
     'lỗi, đó là lỗi của tôi, cái màu xanh không phải để bán"}\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='Tạm biệt!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
     Document(page_content='Ôi không sao cả! Tạm biệt', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
     Document(page_content='Không, tôi xin lỗi, đó là lỗi của tôi, cái màu xanh không phải để bán', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]

Một lựa chọn khác là thiết lập jq_schema='.' và cung cấp 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})]

Trích xuất dữ liệu về siêu dữ liệu

Thường thì chúng ta muốn bao gồm các siêu dữ liệu từ một tệp JSON vào tài liệu mà chúng ta tạo từ nội dung.

Dưới đây là cách sử dụng JSONLoader để trích xuất siêu dữ liệu.

Trong ví dụ trước đó, chúng ta không thu thập siêu dữ liệu, nhưng đã quản lý chỉ định trong schema vị trí từ mà giá trị page_content có thể được trích xuất trực tiếp.

.messages[].content

Trong ví dụ hiện tại, chúng ta cần thông báo cho trình tải lặp qua các bản ghi trong trường messages. Sau đó, jq_schema phải là:

.messages[]

Điều này cho phép chúng ta truyền các bản ghi (từ điển) vào "metadata_func" mà phải được thực hiện. "metadata_func" chịu trách nhiệm xác định thông tin của bản ghi nào nên được bao gồm trong các siêu dữ liệu để được lưu trữ trong đối tượng "Document" cuối cùng.

Ngoài ra, giờ đây chúng ta phải cụ thể chỉ định tham số content_key trong trình tải để trích xuất giá trị "page_content" từ khóa nào trong bản ghi.

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)
[Tài liệu(trang_nội_dung='Tạm biệt!', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'tên_người_gửi': 'Người dùng 2', 'timestamp_ms': 1675597571851}),
     Tài liệu(trang_nội_dung='Không sao đâu! Tạm biệt', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'tên_người_gửi': 'Người dùng 1', 'timestamp_ms': 1675597435669}),
     Tài liệu(trang_nội_dung='Không, tôi xin lỗi, đó là lỗi của tôi. Đồ xanh không phải là để bán', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3, 'tên_người_gửi': 'Người dùng 2', 'timestamp_ms': 1675596277579}),
     Tài liệu(trang_nội_dung='Tôi nghĩ bạn đang bán cái xanh kia!', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4, 'tên_người_gửi': 'Người dùng 1', 'timestamp_ms': 1675595140251}),
     Tài liệu(trang_nội_dung="Tôi không quan tâm cái túi này. Tôi quan tâm cái xanh kia!", dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5, 'tên_người_gửi': 'Người dùng 1', 'timestamp_ms': 1675595109305}),
     Tài liệu(trang_nội_dung='Đây là $129', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6, 'tên_người_gửi': 'Người dùng 2', 'timestamp_ms': 1675595068468}),
     Tài liệu(trang_nội_dung='', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7, 'tên_người_gửi': 'Người dùng 2', 'timestamp_ms': 1675595060730}),
     Tài liệu(trang_nội_dung='Online nó ít nhất là $100', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8, 'tên_người_gửi': 'Người dùng 2', 'timestamp_ms': 1675595045152}),
     Tài liệu(trang_nội_dung='Bạn muốn bao nhiêu tiền?', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9, 'tên_người_gửi': 'Người dùng 1', 'timestamp_ms': 1675594799696}),
     Tài liệu(trang_nội_dung='Buổi sáng tốt lành! $50 quá thấp.', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10, 'tên_người_gửi': 'Người dùng 2', 'timestamp_ms': 1675577876645}),
     Tài liệu(trang_nội_dung='Xin chào! Tôi quan tâm đến cái túi của bạn. Tôi đề xuất $50. Hãy cho biết nếu bạn quan tâm. Cảm ơn!', dữ_liệu={'nguồn': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11, 'tên_người_gửi': 'Người dùng 1', 'timestamp_ms': 1675549022673})]

Ở đây, chúng ta có thể thấy rằng những tệp tin này đã chứa các dữ liệu về nội dung chúng ta đã trích xuất.

Hàm metadata_func

Như được thể hiện ở trên, metadata_func nhận thông tin siêu dữ liệu mặc định được tạo ra bởi JSONLoader. Điều này cho phép người dùng hoàn toàn kiểm soát định dạng của thông tin siêu dữ liệu.

Ví dụ, thông tin siêu dữ liệu mặc định chứa các khóa sourceseq_num. Tuy nhiên, dữ liệu JSON cũng có thể chứa các khóa này. Người dùng có thể sử dụng metadata_func để đổi tên các khóa mặc định và sử dụng các khóa từ dữ liệu JSON.

Ví dụ dưới đây thể hiện cách sửa đổi source để chỉ bao gồm thông tin nguồn tệp liên quan đến thư mục 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}),
     ...
     ...
     ... (nội dung còn lại không thay đổi vì mục đích ngắn gọn) ...
     ...
     ...
]

Cấu trúc JSON thông thường để sử dụng mẫu jq

Danh sách sau cung cấp các jq_schema có thể sử dụng làm tài liệu tham khảo để trích xuất nội dung từ dữ liệu JSON dựa trên cấu trúc.

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

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

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