如何加载 JSON 
JSON(JavaScript 对象表示) 是一种开放标准文件格式和数据交换格式,使用人类可读的文本来存储和传输由属性-值对和数组(或其他可序列化值)组成的数据对象。
JSON Lines 是一种文件格式,其中每一行都是一个有效的 JSON 值。
LangChain 实现了一个 JSONLoader,用于将 JSON 和 JSONL 数据转换为 LangChain Document 对象。它使用指定的 jq schema 来解析 JSON 文件,允许将特定字段提取到 LangChain Document 的内容和元数据中。
它使用了 jq python 包。查看这个 手册 以获取有关 jq 语法的详细文档。
这里我们将演示:
- 如何将 JSON 和 JSONL 数据加载到 LangChain - Document的内容中;
- 如何将 JSON 和 JSONL 数据加载到与 - Document相关的元数据中。
#!pip install jqfrom langchain_community.document_loaders import JSONLoaderimport json
from pathlib import Path
from pprint import pprintfile_path='./example_data/facebook_chat.json'
data = json.loads(Path(file_path).read_text())pprint(data)使用 JSONLoader 
假设我们有兴趣提取 JSON 数据中 messages 键下 content 字段中的值。通过 JSONLoader 可轻松实现如下。
JSON 文件 
loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[].content',
    text_content=False)
data = loader.load()pprint(data)JSON Lines 文件 
如果要从 JSON Lines 文件中加载文档,可以传递 json_lines=True,并指定 jq_schema 以从单个 JSON 对象中提取 page_content。
file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())loader = JSONLoader(
    file_path='./example_data/facebook_chat_messages.jsonl',
    jq_schema='.content',
    text_content=False,
    json_lines=True)
data = loader.load()pprint(data)另一个选项是设置 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)带有 jq schema content_key 的 JSON 文件 
要使用 jq schema 中的 content_key 从 JSON 文件加载文档,请设置 is_content_key_jq_parsable=True。确保 content_key 兼容并可以使用 jq schema 进行解析。
file_path = './sample.json'
pprint(Path(file_path).read_text())loader = JSONLoader(
    file_path=file_path,
    jq_schema=".data[]",
    content_key=".attributes.message",
    is_content_key_jq_parsable=True,
)
data = loader.load()pprint(data)提取元数据 
通常,我们希望将 JSON 文件中可用的元数据包含在从内容创建的文档中。
以下演示了如何使用 JSONLoader 提取元数据。
需要注意一些关键更改。在之前的示例中,我们没有收集元数据,我们设法直接在模式中指定 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='./example_data/facebook_chat.json',
    jq_schema='.messages[]',
    content_key="content",
    metadata_func=metadata_func
)
data = loader.load()pprint(data)现在,您会发现文档中包含与我们提取的内容相关的元数据。
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)带有 jq 模式的常见 JSON 结构 
下面的列表提供了用户可以根据结构从 JSON 数据中提取内容的可能的 jq_schema 参考。
