如何通过Node.js/Java API实现MLCP式文档拆分转换生成多文档?
我来帮你梳理下怎么用Node.js和Java API实现和MLCP一样的文档拆分多插入功能,之前我也折腾过类似的场景,踩过一些坑,分享给你:
Node.js API 实现方案
你有两种路径可选:客户端本地拆分后批量写入,或者调用服务器端转换模块生成多文档,两种方式各有适用场景。
1. 客户端本地拆分(灵活易调试)
这种方式适合业务逻辑复杂、需要在本地做额外处理的场景,先读取原始文档,拆分后批量写入MarkLogic:
首先确保安装了MarkLogic Node.js客户端:
npm install marklogic
示例代码:
const marklogic = require('marklogic'); // 初始化数据库客户端 const db = marklogic.createDatabaseClient({ host: 'localhost', port: 8000, user: 'admin', password: 'admin', authType: 'DIGEST' }); // 模拟你的文档拆分逻辑(和MLCP转换逻辑一致) function splitOriginalDoc(originalDoc) { // 这里替换成你的实际拆分规则 return [ { uri: `/split/doc-${Date.now()}-1.json`, value: { content: originalDoc.content.part1, sourceUri: originalDoc.uri } }, { uri: `/split/doc-${Date.now()}-2.json`, value: { content: originalDoc.content.part2, sourceUri: originalDoc.uri } } ]; } // 读取原始文档并拆分写入 db.documents.read('/original/source-doc.json') .result() .then(originalDocs => { const splitDocuments = splitOriginalDoc(originalDocs[0]); // 批量写入拆分后的文档 return db.documents.write( splitDocuments.map(doc => ({ uri: doc.uri, content: doc.value, collections: ['split-documents'] // 可选:添加集合标签 })) ).result(); }) .then(response => { console.log('拆分文档写入成功:', response.documents.map(d => d.uri)); }) .catch(err => { console.error('操作失败:', err); });
2. 调用服务器端转换模块(适合大文档,减少数据传输)
如果原始文档很大,在客户端处理会占用过多带宽,推荐把拆分逻辑写成MarkLogic服务器端的JavaScript模块,然后用Node.js客户端调用:
步骤1:在MarkLogic服务器上创建转换模块
比如创建/ext/split-transform.sjs(放在Modules数据库):
// 服务器端拆分转换逻辑 function transform(context, params, content) { // 解析原始文档内容 const originalContent = content.toObject(); // 执行拆分逻辑(和你MLCP用的逻辑一致) return [ { uri: `/split/server-side-1.json`, value: { data: originalContent.sectionA } }, { uri: `/split/server-side-2.json`, value: { data: originalContent.sectionB } } ]; } exports.transform = transform;
步骤2:Node.js客户端调用转换
db.documents.write({ uri: '/original/large-source-doc.json', transform: { name: 'split-transform', // 指定服务器端转换模块名 parameters: {} // 可选:传递转换参数 } }) .result() .then(response => { console.log('服务器端拆分并写入完成'); }) .catch(err => { console.error('转换失败:', err); });
Java API 实现方案
Java API同样支持客户端拆分和服务器端转换两种方式,下面是具体示例:
1. 客户端本地拆分批量写入
import com.marklogic.client.DatabaseClient; import com.marklogic.client.DatabaseClientFactory; import com.marklogic.client.document.JSONDocumentManager; import com.marklogic.client.io.StringHandle; import com.marklogic.client.io.DocumentMetadataHandle; import org.json.JSONObject; import org.json.JSONArray; public class DocSplitterClient { public static void main(String[] args) { // 初始化数据库客户端 DatabaseClient client = DatabaseClientFactory.newClient( "localhost", 8000, new DatabaseClientFactory.DigestAuthContext("admin", "admin") ); try { JSONDocumentManager docMgr = client.newJSONDocumentManager(); // 读取原始文档 StringHandle originalHandle = new StringHandle(); docMgr.read("/original/source-doc.json", originalHandle); JSONObject originalDoc = new JSONObject(originalHandle.get()); // 执行拆分逻辑 JSONArray splitDocs = splitDocument(originalDoc); // 批量写入拆分后的文档 for (int i = 0; i < splitDocs.length(); i++) { JSONObject splitItem = splitDocs.getJSONObject(i); String targetUri = splitItem.getString("uri"); JSONObject content = splitItem.getJSONObject("value"); StringHandle contentHandle = new StringHandle(content.toString()); DocumentMetadataHandle metadata = new DocumentMetadataHandle(); metadata.getCollections().add("split-documents"); docMgr.write(targetUri, metadata, contentHandle); } System.out.println("所有拆分文档写入完成"); } finally { client.release(); } } // 自定义拆分逻辑 private static JSONArray splitDocument(JSONObject original) { JSONArray result = new JSONArray(); // 替换成你的实际拆分规则 JSONObject doc1 = new JSONObject(); doc1.put("uri", "/split/java-client-1.json"); doc1.put("value", new JSONObject().put("data", original.get("section1"))); JSONObject doc2 = new JSONObject(); doc2.put("uri", "/split/java-client-2.json"); doc2.put("value", new JSONObject().put("data", original.get("section2"))); result.put(doc1); result.put(doc2); return result; } }
2. 服务器端转换调用
步骤1:创建服务器端XQuery转换模块
比如/modules/split-transform.xqy:
xquery version "1.0-ml"; module namespace split = "http://example.com/split-transform"; declare function split:transform( $context as map:map, $params as map:map, $content as document-node() ) as document-node()* { let $original := fn:json-doc($content) let $doc1 := json:object() => map:put("uri", "/split/java-server-1.json") => map:put("value", json:object() => map:put("data", $original?section1)) let $doc2 := json:object() => map:put("uri", "/split/java-server-2.json") => map:put("value", json:object() => map:put("data", $original?section2)) return ( xdmp:document-insert($doc1?uri, $doc1?value), xdmp:document-insert($doc2?uri, $doc2?value) ) };
步骤2:Java客户端调用转换
import com.marklogic.client.DatabaseClient; import com.marklogic.client.DatabaseClientFactory; import com.marklogic.client.document.DocumentManager; import com.marklogic.client.transform.ServerTransform; public class ServerTransformSplitter { public static void main(String[] args) { DatabaseClient client = DatabaseClientFactory.newClient( "localhost", 8000, new DatabaseClientFactory.DigestAuthContext("admin", "admin") ); try { DocumentManager docMgr = client.newDocumentManager(); // 指定服务器端转换模块 ServerTransform transform = new ServerTransform("split-transform"); // 对原始文档应用转换 docMgr.write("/original/large-source-doc.json", transform, null); System.out.println("服务器端拆分转换执行完成"); } finally { client.release(); } } }
注意事项
- 如果你之前用Node.js API只能生成单个文档,大概率是没有做批量写入,或者服务器端转换模块没有正确返回多文档数组(必须是包含
uri和value字段的对象数组)。 - 服务器端转换模块需要放在MarkLogic的Modules数据库中,并且确保执行用户有模块的读取和执行权限。
- 大文档优先用服务器端转换,减少客户端和服务器之间的数据传输开销。
内容的提问来源于stack exchange,提问作者Arthur Zangiev
相关产品推荐
相关产品推荐

