public void performWork(LuceneWork work, IndexWriter writer) {
    final Class<?> entityType = work.getEntityClass();
    final Serializable id = work.getId();
    log.tracef("Removing %s#%s by query.", entityType, id);
    DocumentBuilderIndexedEntity<?> builder = workspace.getDocumentBuilder(entityType);

    BooleanQuery entityDeletionQuery = new BooleanQuery();

    Query idQueryTerm;
    if (isIdNumeric(builder)) {
      idQueryTerm = NumericFieldUtils.createExactMatchQuery(builder.getIdKeywordName(), id);
    } else {
      idQueryTerm = new TermQuery(builder.getTerm(id));
    }
    entityDeletionQuery.add(idQueryTerm, BooleanClause.Occur.MUST);

    Term classNameQueryTerm = new Term(ProjectionConstants.OBJECT_CLASS, entityType.getName());
    TermQuery classNameQuery = new TermQuery(classNameQueryTerm);
    entityDeletionQuery.add(classNameQuery, BooleanClause.Occur.MUST);

    try {
      writer.deleteDocuments(entityDeletionQuery);
    } catch (Exception e) {
      String message = "Unable to remove " + entityType + "#" + id + " from index.";
      throw new SearchException(message, e);
    }
  }
 @Override
 public void performWork(LuceneWork work, IndexWriterDelegate delegate, IndexingMonitor monitor) {
   final Serializable id = work.getId();
   final String tenantId = work.getTenantId();
   final Class<?> managedType = work.getEntityClass();
   DocumentBuilderIndexedEntity builder = workspace.getDocumentBuilder(managedType);
   try {
     if (DeleteWorkExecutor.isIdNumeric(builder)) {
       log.tracef(
           "Deleting %s#%s by query using an IndexWriter#updateDocument as id is Numeric",
           managedType, id);
       Query exactMatchQuery =
           NumericFieldUtils.createExactMatchQuery(builder.getIdKeywordName(), id);
       BooleanQuery.Builder deleteDocumentsQueryBuilder = new BooleanQuery.Builder();
       deleteDocumentsQueryBuilder.add(exactMatchQuery, Occur.FILTER);
       if (tenantId != null) {
         TermQuery tenantTermQuery =
             new TermQuery(new Term(DocumentBuilderIndexedEntity.TENANT_ID_FIELDNAME, tenantId));
         deleteDocumentsQueryBuilder.add(tenantTermQuery, Occur.FILTER);
       }
       delegate.deleteDocuments(deleteDocumentsQueryBuilder.build());
       // no need to log the Add operation as we'll log in the delegate
       this.addDelegate.performWork(work, delegate, monitor);
     } else {
       log.tracef("Updating %s#%s by id using an IndexWriter#updateDocument.", managedType, id);
       Term idTerm = new Term(builder.getIdKeywordName(), work.getIdInString());
       Map<String, String> fieldToAnalyzerMap = work.getFieldToAnalyzerMap();
       ScopedAnalyzerReference analyzerReference = builder.getAnalyzerReference();
       analyzerReference =
           AddWorkExecutor.updateAnalyzerMappings(
               workspace, analyzerReference, fieldToAnalyzerMap);
       delegate.updateDocument(idTerm, work.getDocument(), analyzerReference);
     }
     workspace.notifyWorkApplied(work);
   } catch (Exception e) {
     String message = "Unable to update " + managedType + "#" + id + " in index.";
     throw new SearchException(message, e);
   }
   if (monitor != null) {
     monitor.documentsAdded(1l);
   }
 }