如何从Vespa的Processor向DocumentProcessing Pipeline发送自定义DocumentOperation?
解决Vespa自定义HTTP请求无法触发DocumentProcessor链的问题
根据你的描述,核心问题在于自定义HTTP请求的处理流程没有正确衔接文档处理器链——你在MyObjectProcessor中新建了Processing实例,但这个实例没有被纳入当前的执行链路,导致后续的MyFirstDocumentProcessor无法接收到操作。下面是具体的解决思路和代码调整方案:
1. 调整MyObjectProcessor:复用当前Processing实例,而非新建
不要创建全新的Processing对象,而是在方法传入的Processing实例中添加DocumentPut操作,这样后续的DocumentProcessor就能识别并处理这个操作:
@Override public boolean process(Processing processing, Execution execution) { // 从Processing上下文获取HTTP请求体(需在HTTP Handler中提前存入) String requestBody = processing.getContext().get("requestBody").toString(); // 这里添加你的JSON反序列化逻辑,解析请求体到对应字段 // ... // 创建Document并生成DocumentPut操作 DocumentType type = localDocHandler.getDocumentTypeManager().getDocumentType("my_doc"); DocumentId id = new DocumentId("id:default:my_doc::2"); // 建议从JSON解析实际业务ID Document document = new Document(type, id); // 从反序列化结果设置Document字段 document.setFieldValue("your_field", parsedValue); // 将DocumentPut添加到当前Processing实例中 DocumentPut docPut = new DocumentPut(document); processing.addOperation(docPut); return true; // 返回true让Execution继续执行后续处理器 }
2. 在MyImportsCustomHandler中正确触发处理器链
自定义HTTP Handler需要手动创建Processing、传递请求数据,并获取预配置的执行链来启动处理流程:
@Override public void handle(HttpRequest request, HttpResponse response) { // 1. 执行请求验证逻辑(权限、格式检查等) if (!validateRequest(request)) { response.setStatus(HttpStatus.BAD_REQUEST); response.setBody("Invalid request format or permissions"); return; } // 2. 创建空Processing实例,将请求体存入上下文供后续处理器使用 Processing processing = Processing.createEmpty(); processing.getContext().put("requestBody", request.getBody().asString()); // 3. 获取预配置的处理器链执行器(需在services.xml中配置对应链) Execution execution = getContainer().getComponent(DocumentProcessingHandler.class) .createExecution("my_import_processing_chain"); // 4. 启动处理器链执行 execution.process(processing); // 5. 返回处理结果响应 response.setStatus(HttpStatus.OK); response.setBody("Import request processed successfully"); }
3. 确保services.xml中正确配置处理器链
需要将MyObjectProcessor和MyFirstDocumentProcessor纳入同一个处理器链,并让HTTP Handler绑定到指定路径:
<container id="your-container"> <!-- 配置文档处理器链 --> <document-processing> <chain id="my_import_processing_chain"> <processor id="myObjectProcessor" class="com.yourpackage.MyObjectProcessor"/> <processor id="myFirstDocumentProcessor" class="com.yourpackage.MyFirstDocumentProcessor"/> </chain> </document-processing> <!-- 配置HTTP服务与自定义Handler --> <http> <server id="main-server" port="8080"> <handler id="myImportsHandler" class="com.yourpackage.MyImportsCustomHandler"> <binding>post /my_imports</binding> </handler> </server> </http> </container>
4. 验证MyFirstDocumentProcessor的逻辑
确保你的文档处理器能正确识别并处理DocumentPut操作:
@Override public Progress process(DocumentOperation op, Execution execution) { if (op instanceof DocumentPut) { DocumentPut putOp = (DocumentPut) op; Document targetDoc = putOp.getDocument(); // 执行字段设置、数据校验等业务逻辑 targetDoc.setFieldValue("import_timestamp", System.currentTimeMillis()); // 如果需要将文档写入Content节点,返回Progress.CONTINUE让默认处理器完成存储 // 如果仅需本地处理,返回Progress.DONE return Progress.CONTINUE; } return Progress.CONTINUE; }
核心原因说明
你之前新建Processing实例的操作脱离了当前的执行链路——Vespa的Execution只会处理传入的Processing对象,新建的实例不会自动进入后续处理器链。复用方法传入的Processing并添加DocumentOperation,才能让DocumentProcessor正确承接处理流程。
内容的提问来源于stack exchange,提问作者AGuereca
相关产品推荐
相关产品推荐

