Class SolrUtil
- java.lang.Object
-
- com.acumenvelocity.ath.common.SolrUtil
-
public class SolrUtil extends Object
-
-
Constructor Summary
Constructors Constructor Description SolrUtil()
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static StringbuildDocSegSolrId(UUID docId, Long position)static StringbuildTmSegSolrId(UUID tmId, String sourceWithCodes)static booleancheckTmFuzzyScore(int score)static StringescapeQueryCharsNoWs(String s)static org.apache.solr.common.SolrDocumentgetDocumentByDocId(UUID docId)static org.apache.solr.common.SolrInputDocumentgetDocumentBySolrId(org.apache.solr.client.solrj.SolrClient solrClient, String coreName, String id)Fetches a SolrInputDocument by its unique ID.static org.apache.solr.common.SolrDocumentgetDocumentSegment(UUID docId, UUID docSegId)static longgetNumDocuments()static longgetNumDocuments(String coreName)static longgetNumDocuments(String coreName, String query)static org.apache.solr.common.SolrDocumentgetTmByTmId(UUID tmId)static voidmoveDocSegmentsBelow(UUID docId, Long position)Shifts document segments at or below a specified position down by one position.static StringnormalizeQuery(String query)static StringnormalizeQuery(String query, int maxLen)static voidsafeAddField(net.sf.okapi.common.resource.ITextUnit tu, org.apache.solr.common.SolrInputDocument doc, String name, String value)static voidsafeAddField(net.sf.okapi.common.resource.ITextUnit tu, org.apache.solr.common.SolrInputDocument doc, String name, String value, boolean strictValueCheck)static voidsafeAddField(org.apache.solr.common.SolrInputDocument doc, String name, String value)static voidsafeAddField(org.apache.solr.common.SolrInputDocument doc, String name, UUID value)static StringsafeGetField(org.apache.solr.common.SolrDocument doc, String fieldName, String defVal)Safely gets a field value from a SolrDocument and converts to String.static IntegersafeGetIntField(org.apache.solr.common.SolrDocument doc, String fieldName, Integer defVal)static LongsafeGetLongField(org.apache.solr.common.SolrDocument doc, String fieldName, Long defVal)static voidsafeSetField(net.sf.okapi.common.resource.ITextUnit tu, org.apache.solr.common.SolrInputDocument doc, String name, String value)static voidsafeSetField(net.sf.okapi.common.resource.ITextUnit tu, org.apache.solr.common.SolrInputDocument doc, String name, String value, boolean strictValueCheck)static voidsafeSetField(org.apache.solr.common.SolrInputDocument doc, String name, String value)static voidsafeSetField(org.apache.solr.common.SolrInputDocument doc, String name, UUID value)static org.apache.solr.common.SolrInputDocumenttoInputDocument(org.apache.solr.common.SolrDocument solrDoc)Converts a SolrDocument to a SolrInputDocument for reindexing or updates.
-
-
-
Method Detail
-
toInputDocument
public static org.apache.solr.common.SolrInputDocument toInputDocument(org.apache.solr.common.SolrDocument solrDoc)
Converts a SolrDocument to a SolrInputDocument for reindexing or updates.This method creates a new SolrInputDocument by copying all user-defined fields from the source SolrDocument. Internal Solr fields (those starting with underscore) are automatically excluded to allow Solr to manage its own metadata fields like
_version_,_root_, and_nest_path_.This is commonly used when:
- Reading documents from Solr, modifying them, and writing them back
- Copying documents between collections
- Performing batch updates on existing documents
Example Usage:
SolrDocument doc = // ... retrieved from Solr query SolrInputDocument inputDoc = toInputDocument(doc); inputDoc.setField("status", "updated"); solr.add(inputDoc);Note: This method uses
setField()rather thanaddField()to prevent duplicate field values, ensuring each field appears only once in the resulting document.- Parameters:
solrDoc- the source SolrDocument to convert; must not be null- Returns:
- a new SolrInputDocument containing all non-internal fields from the source document
- Throws:
NullPointerException- if solrDoc is null
-
getDocumentBySolrId
public static org.apache.solr.common.SolrInputDocument getDocumentBySolrId(org.apache.solr.client.solrj.SolrClient solrClient, String coreName, String id) throws ExceptionFetches a SolrInputDocument by its unique ID.- Parameters:
solrClient- The SolrClient instance.coreName- The Solr core or collection name.id- The unique document ID.- Returns:
- The SolrInputDocument, or null if not found.
- Throws:
Exception- if Solr query fails.
-
getDocumentByDocId
public static org.apache.solr.common.SolrDocument getDocumentByDocId(UUID docId)
-
getDocumentSegment
public static org.apache.solr.common.SolrDocument getDocumentSegment(UUID docId, UUID docSegId)
-
getTmByTmId
public static org.apache.solr.common.SolrDocument getTmByTmId(UUID tmId)
-
moveDocSegmentsBelow
public static void moveDocSegmentsBelow(UUID docId, Long position)
Shifts document segments at or below a specified position down by one position.This method is used to make room for inserting a new document segment at a specific position by incrementing the position of all existing segments at or after that position. The method handles both normal position updates and edge cases where position data may be missing or invalid.
Normal Operation:
- Queries Solr for all document segments matching the given docId with position >= the specified position
- Increments each matching document's position by 1
- Recalculates the Solr ID for each document based on the new position using
buildDocSegSolrId(UUID, Long) - Writes all modified documents back to Solr in a batch operation, overwriting the old documents
Edge Case Handling - Missing Position Data:
When a document's position field is missing, null, or invalid (defaults to 0), incrementing by 1 results in a new position of 1. This creates a potential conflict with existing documents already at position 1 or above. To handle this scenario:- The method detects when any documents will be moved to position 1
- Executes an additional query to find all existing documents at position >= 1 that weren't already included in the initial query
- Shifts these additional documents down by incrementing their positions as well
- Ensures no position conflicts occur when documents with failed position reads are inserted at the head
Example Usage:
// Inserting a new segment at position 3 - all segments at positions 3, 4, 5, etc. // will be moved to positions 4, 5, 6, etc. moveDocSegmentsBelow(docId, 3L);
Thread Safety and Distributed Locking: This method is thread-safe across multiple worker nodes in a distributed system. It uses Solr-based distributed locking to ensure that only one worker node can modify segments for a given docId at a time. The method will retry up to 3 times with exponential backoff if the lock is already held by another node. Concurrent operations on different documents can proceed in parallel without blocking each other.
Error Handling: All exceptions are silently caught and ignored. The method follows a fail-silent pattern and will not throw exceptions to the caller. Locks are always released in a finally block to prevent deadlocks.
Internal Fields: The Solr internal field
_version_is explicitly excluded from document copying to allow Solr to manage its own versioning for optimistic concurrency control.- Parameters:
docId- the UUID of the document whose segments should be shifted; must not be nullposition- the position threshold; all segments at this position or higher will be shifted down (position incremented by 1); must not be null- See Also:
buildDocSegSolrId(UUID, Long),AthIndex.getMany(String, String, Map, Class),AthIndex.createMany(String, List)
-
checkTmFuzzyScore
public static boolean checkTmFuzzyScore(int score)
-
escapeQueryCharsNoWs
public static String escapeQueryCharsNoWs(String s)
- Returns:
- See Also:
ClientUtils
-
getNumDocuments
public static long getNumDocuments()
-
getNumDocuments
public static long getNumDocuments(String coreName)
-
safeAddField
public static void safeAddField(net.sf.okapi.common.resource.ITextUnit tu, org.apache.solr.common.SolrInputDocument doc, String name, String value) throws AthException- Throws:
AthException
-
safeAddField
public static void safeAddField(org.apache.solr.common.SolrInputDocument doc, String name, String value)
-
safeAddField
public static void safeAddField(org.apache.solr.common.SolrInputDocument doc, String name, UUID value)
-
safeAddField
public static void safeAddField(net.sf.okapi.common.resource.ITextUnit tu, org.apache.solr.common.SolrInputDocument doc, String name, String value, boolean strictValueCheck) throws AthException- Throws:
AthException
-
safeSetField
public static void safeSetField(net.sf.okapi.common.resource.ITextUnit tu, org.apache.solr.common.SolrInputDocument doc, String name, String value) throws AthException- Throws:
AthException
-
safeSetField
public static void safeSetField(net.sf.okapi.common.resource.ITextUnit tu, org.apache.solr.common.SolrInputDocument doc, String name, String value, boolean strictValueCheck) throws AthException- Throws:
AthException
-
safeSetField
public static void safeSetField(org.apache.solr.common.SolrInputDocument doc, String name, String value)
-
safeSetField
public static void safeSetField(org.apache.solr.common.SolrInputDocument doc, String name, UUID value)
-
safeGetField
public static String safeGetField(org.apache.solr.common.SolrDocument doc, String fieldName, String defVal)
Safely gets a field value from a SolrDocument and converts to String. Returns defVal if field is null or empty.
-
safeGetLongField
public static Long safeGetLongField(org.apache.solr.common.SolrDocument doc, String fieldName, Long defVal)
-
safeGetIntField
public static Integer safeGetIntField(org.apache.solr.common.SolrDocument doc, String fieldName, Integer defVal)
-
-