FileNet批量搜索和更新

时间:2017-05-22 17:12:41

标签: batch-processing filenet-p8 filenet-content-engine

我有一个要求,其中,我必须更新objectstore中数百万个文档的文档元数据。所以我用下面的方法写了一个简单的java独立文件

SearchSQL documentSearchSQL = new SearchSQL();
String selectQuery = "Id ";
String classSymbolicName="Document_Class_Name";
String myAlias1 = "r";
String whereClause="r.Document_Type_Code='DIRMKTGDOC'and VersionStatus=1"
boolean subClassesToo=false;
documentSearchSQL.setSelectList(selectQuery);
documentSearchSQL.setFromClauseInitialValue(classSymbolicName, myAlias1, subClassesToo);
documentSearchSQL.setWhereClause(whereClause);

UpdatingBatch updatingBatch =null;
SearchScope searchScope = new SearchScope(p8ObjectStore);
RepositoryRowSet rowSet = searchScope.fetchRows(documentSearchSQL, new Integer(10000), null, new Boolean(true));
PageIterator pageIterator = rowSet.pageIterator();
RepositoryRow row;
Document document = null;

while(pageIterator.nextPage()){
Object[] rowArray = pageIterator.getCurrentPage();
updatingBatch = UpdatingBatch.createUpdatingBatchInstance(p8ObjectStore.get_Domain(),RefreshMode.NO_REFRESH); 
for (int i = 0; i < rowArray.length; i++) {
row= (RepositoryRow)rowArray[i];
Properties documentProps = row.getProperties();
document = Factory.Document.fetchInstance(p8ObjectStore, documentProps.getIdValue("Id"), null);
// I have the metadata symbolic name and its values within HashMap. So iterating Map to set the values
for(Map.Entry<String, ArrayList<String>> documentMetadata : documentMetadataValues.entrySet()){
document.getProperties().putObjectValue(documentMetadata.getKey(), documentMetadata.getValue().get(1));
}
updatingBatch.add(document, null);
}
updatingBatch.updateBatch();

当我在docVersion上运行查询时,我发现大约有700K文档符合标准,并期望所有这些文档都得到更新。当我运行该程序时,它更新了大约390k文档然后给出了错误

com.filenet.api.exception.EngineRuntimeException: FNRCA0031E: API_UNABLE_TO_USE_CONNECTION: The URI for server communication cannot be determined from the connection object http://server:port/wsi/FNCEWS40MTOM. Message was: Connection refused: connect

有没有更好的方法来实现这一目标?此外,我将使用组件队列在生产中运行此工具。

1 个答案:

答案 0 :(得分:3)

通过使用基于脚本的批量操作或扫描,您实际上有2个更好的选择。

批量操作

您可以将批量操作应用于查询的搜索结果。在查询运行时或查询运行后,将执行这些操作。

  1. 访问管理控制台中的对象库搜索
  2. SQL视图选项卡上,输入相应的查询。
  3. 批量操作标签上,选择启用
  4. 在“脚本”部分中,选择运行脚本
  5. 在“脚本”字段中输入您的JavaScript代码。有关更多信息,请参阅下面的示例。
  6. 点击运行。管理控制台运行查询和JavaScript操作。
  7. importClass(Packages.com.filenet.api.property.Properties);
    importClass(Packages.com.filenet.api.constants.RefreshMode);
    
    function OnCustomProcess(CEObject) {
      CEObject.refresh();
      CEObject.getProperties().putValue("DocumentTitle", "Test1");
      CEObject.save(RefreshMode.REFRESH);
    }

    有关详情,请查看知识中心here

    自定义扫描作业

    或者,您可以使用自定义扫描作业。扫描是您配置为处理数据库表中的对象的后台服务的实例。 如果对象满足配置的条件,则扫描会对对象执行操作。 扫描包括扫描操作扫描作业

    1. 在域导航窗格中,单击对象库。在对象中 存储导航窗格,右键单击扫描管理&gt;扫 操作文件夹,然后点击新扫描操作
    2. 选择操作类型。对于此示例,让我们选择Java脚本,下面列出了一个示例,并完成向导。
    3. 在域导航窗格中,选择对象库。 在对象库导航窗格中,选择扫描管理&gt;工作大扫除&gt;自定义作业文件夹并单击新建,参考我们刚刚创建的操作,然后完成向导。 现在你们都准备好了!运行扫描工作
    4. importPackage(Packages.com.filenet.api.core);
      importPackage(Packages.com.filenet.api.constants);
      importPackage(Packages.com.filenet.api.exception);
      importPackage(Packages.com.filenet.api.sweep);
      importPackage(Packages.com.filenet.api.engine);
      
      // Implement for custom job and queue sweeps.
      function onSweep(sweepObject, sweepItems) {
        var hcc = HandlerCallContext.getInstance();
        hcc.traceDetail("Entering CustomSweepHandler.onSweep");
        hcc.traceDetail("sweepObject = " +
          sweepObject.getProperties().getIdValue(PropertyNames.ID) +
          "sweepItems.length = " + sweepItems.length);
      
        // Iterate the sweepItems and change the class.
        idx = 0;
        for (idx = 0; idx < sweepItems.length; idx++) {
          // At the top of your loop, always check to make sure 
          // that the server is not shutting down. 
          // If it is, clean up and return control to the server.
          if (hcc != null && hcc.isShuttingDown()) {
            throw new EngineRuntimeException(ExceptionCode.E_BACKGROUND_TASK_TERMINATED,
              this.constructor.name + " is terminating prematurely because the server is shutting down");
          }
      
          var item = sweepItems[idx].getTarget();
          String msg = "sweepItems[" + idx + "]= " + item.getProperties().getIdValue("ID");
          hcc.traceDetail(msg);
      
          try {
            var CEObject = Document(item);
            CEObject.getProperties().putValue("DocumentTitle", "Test1");
            CEObject.save(RefreshMode.NO_REFRESH);
      
            // Set outcome to PROCESSED if item processed successfully.
            sweepItems[idx].setOutcome(SweepItemOutcome.PROCESSED,
              "item processed by " + this.constructor.name);
          }
          // Set failure status on objects that fail to process.
          catch (ioe) {
            sweepItems[idx].setOutcome(SweepItemOutcome.FAILED, "CustomSweepHandler: " +
              ioe.rhinoException.getMessage());
          }
        }
        hcc.traceDetail("Exiting CustomSweepHandler.onSweep");
      }
      
      /* 
       * Called automatically when the handler is invoked by a custom sweep job 
       * or sweep policy. Specify properties required by the handler, if any.
       * If you return an empty array, then all properties are fetched.
       */
      function getRequiredProperties() {
        var pnames = ['Id', 'DocumentTitle'];
        return pnames.toString();
      }

      有关扫描作业的更多信息,请查看链接here