Langchain.js JSONLoader加载JSON异常:生成13个文档而非3个求助
解决LangChain.js JSONLoader生成过多Document的问题
问题原因
LangChain.js的JSONLoader默认会递归遍历JSON的所有键值节点,把每个子项都拆成独立的Document。如果你的职位JSON是嵌套结构,就会出现3个职位却生成13个Document的情况——多余的Document都是JSON里的子字段(比如skills数组的每个元素、单个字段值等)。
解决方案:用jq表达式精准提取目标数据
要让Loader只按单个职位生成Document,需要通过jq参数指定提取规则,只抓取数组里的每个职位对象。
1. 先明确你的JSON结构
假设你的职位数据JSON是这种格式(外层有包裹对象):
{ "positions": [ { "jobTitle": "前端开发", "requiredExperience": "2年", "skills": ["JavaScript", "Vue"] }, { "jobTitle": "后端开发", "requiredExperience": "3年", "skills": ["Node.js", "Redis"] }, { "jobTitle": "测试工程师", "requiredExperience": "1年", "skills": ["Python", "Selenium"] } ] }
2. 修改Loader初始化代码
添加jq参数,指定提取数组中的每个职位元素:
import { JSONLoader } from "langchain/document_loaders/fs/json"; // 初始化Loader,用jq表达式定位每个职位 const loader = new JSONLoader( "./job_data.json", { jq: '.positions[]', // 提取positions数组里的每个职位对象 } ); const documents = await loader.load(); console.log(documents.length); // 输出3,符合预期
3. 如果JSON是直接的职位数组
如果你的JSON文件没有外层包裹,直接是[{}, {}, {}],那么jq表达式用.[]即可:
const loader = new JSONLoader( "./job_data.json", { jq: '.[]', // 提取数组中的每个元素 } );
4. 自定义元数据(可选)
如果需要给每个Document附加元数据(比如职位标题、经验要求),可以添加metadata回调函数:
const loader = new JSONLoader( "./job_data.json", { jq: '.positions[]', metadata: (job) => ({ title: job.jobTitle, experience: job.requiredExperience, }), } );
效果验证
修改后重新运行代码,documents.length会等于3,每个Document的pageContent就是单个职位的完整JSON字符串。后续你可以基于这些Document构建向量存储,实现“找2年经验职位”“匹配JavaScript技能”这类问答功能。
内容的提问来源于stack exchange,提问作者user2570135
相关产品推荐
相关产品推荐

