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); } }
@SuppressWarnings("unchecked") private void index( Object entity, Session session, InstanceInitializer sessionInitializer, ConversionContext conversionContext) throws InterruptedException { // abort if the thread has been interrupted while not in wait(), I/O or similar which themselves // would have // raised the InterruptedException if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } Serializable id = session.getIdentifier(entity); Class<?> clazz = HibernateHelper.getClass(entity); EntityIndexBinding entityIndexBinding = entityIndexBindings.get(clazz); if (entityIndexBinding == null) { // it might be possible to receive not-indexes subclasses of the currently indexed type; // being not-indexed, we skip them. // FIXME for improved performance: avoid loading them in an early phase. return; } EntityIndexingInterceptor interceptor = entityIndexBinding.getEntityIndexingInterceptor(); if (interceptor != null) { IndexingOverride onAdd = interceptor.onAdd(entity); switch (onAdd) { case REMOVE: case SKIP: return; } // default: continue indexing this instance } DocumentBuilderIndexedEntity docBuilder = entityIndexBinding.getDocumentBuilder(); TwoWayFieldBridge idBridge = docBuilder.getIdBridge(); conversionContext.pushProperty(docBuilder.getIdKeywordName()); String idInString = null; try { idInString = conversionContext.setClass(clazz).twoWayConversionContext(idBridge).objectToString(id); } finally { conversionContext.popProperty(); } // depending on the complexity of the object graph going to be indexed it's possible // that we hit the database several times during work construction. AddLuceneWork addWork = docBuilder.createAddWork( tenantId, clazz, entity, id, idInString, sessionInitializer, conversionContext); backend.enqueueAsyncWork(addWork); }