如何加载 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 jq
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)
使用 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
参考。