下面列出了org.apache.lucene.index.IndexableField#stringValue ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public Object decode(LuceneContext context, String path, Field field, LuceneStore annotation, Type type, NavigableMap<String, IndexableField> indexables) {
String from = path;
char character = path.charAt(path.length() - 1);
character++;
String to = path.substring(0, path.length() - 1) + character;
indexables = indexables.subMap(from, true, to, false);
IndexableField indexable = indexables.firstEntry().getValue();
return indexable.stringValue();
}
public String get(String name) {
for (IndexableField f : fields) {
if (f.name().equals(name) && f.stringValue() != null) {
return f.stringValue();
}
}
return null;
}
@Override
public Set<Long> getErrorDocIds() throws IOException
{
Set<Long> errorDocIds = new HashSet<>();
RefCounted<SolrIndexSearcher> refCounted = null;
try
{
refCounted = this.core.getSearcher();
SolrIndexSearcher searcher = refCounted.get();
TermQuery errorQuery = new TermQuery(new Term(FIELD_DOC_TYPE, DOC_TYPE_ERROR_NODE));
DocListCollector docListCollector = new DocListCollector();
searcher.search(errorQuery, docListCollector);
IntArrayList docList = docListCollector.getDocs();
int size = docList.size();
for (int i = 0; i < size; ++i)
{
int doc = docList.get(i);
Document document = searcher.doc(doc, REQUEST_ONLY_ID_FIELD);
IndexableField id = document.getField(FIELD_SOLR4_ID);
String idString = id.stringValue();
if (idString.startsWith(PREFIX_ERROR))
{
idString = idString.substring(PREFIX_ERROR.length());
}
errorDocIds.add(Long.valueOf(idString));
}
}
finally
{
ofNullable(refCounted).ifPresent(RefCounted::decref);
}
return errorDocIds;
}
private static String getFieldString(Document document, String name) {
IndexableField field = document.getField(name);
if (field == null) {
return null;
}
return field.stringValue();
}
private static Object getValueFromField(Object expectedValue, IndexableField field) {
if (expectedValue instanceof String) {
return field.stringValue();
} else if (expectedValue instanceof byte[]) {
return field.binaryValue().bytes;
}
return field.numericValue();
}
static DocumentField of(FieldInfo finfo, IndexableField field, IndexReader reader, int docId)
throws IOException {
Objects.requireNonNull(finfo);
Objects.requireNonNull(reader);
DocumentField dfield = new DocumentField();
dfield.name = finfo.name;
dfield.idxOptions = finfo.getIndexOptions();
dfield.hasTermVectors = finfo.hasVectors();
dfield.hasPayloads = finfo.hasPayloads();
dfield.hasNorms = finfo.hasNorms();
if (finfo.hasNorms()) {
NumericDocValues norms = MultiDocValues.getNormValues(reader, finfo.name);
if (norms.advanceExact(docId)) {
dfield.norm = norms.longValue();
}
}
dfield.dvType = finfo.getDocValuesType();
dfield.pointDimensionCount = finfo.getPointDimensionCount();
dfield.pointNumBytes = finfo.getPointNumBytes();
if (field != null) {
dfield.isStored = field.fieldType().stored();
dfield.stringValue = field.stringValue();
if (field.binaryValue() != null) {
dfield.binaryValue = BytesRef.deepCopyOf(field.binaryValue());
}
dfield.numericValue = field.numericValue();
}
return dfield;
}
/**
* Find words for a more-like-this query former.
*
* @param docNum the id of the lucene document from which to find terms
*/
private PriorityQueue<ScoreTerm> retrieveTerms(int docNum) throws IOException {
Map<String, Map<String, Int>> field2termFreqMap = new HashMap<>();
for (String fieldName : fieldNames) {
final Fields vectors = ir.getTermVectors(docNum);
final Terms vector;
if (vectors != null) {
vector = vectors.terms(fieldName);
} else {
vector = null;
}
// field does not store term vector info
if (vector == null) {
Document d = ir.document(docNum);
IndexableField[] fields = d.getFields(fieldName);
for (IndexableField field : fields) {
final String stringValue = field.stringValue();
if (stringValue != null) {
addTermFrequencies(new StringReader(stringValue), field2termFreqMap, fieldName);
}
}
} else {
addTermFrequencies(field2termFreqMap, vector, fieldName);
}
}
return createQueue(field2termFreqMap);
}
/**
* Returns an array of values of the field specified as the method parameter.
* This method returns an empty array when there are no
* matching fields. It never returns null.
* For a numeric {@link StoredField} it returns the string value of the number. If you want
* the actual numeric field instances back, use {@link #getFields}.
* @param name the name of the field
* @return a <code>String[]</code> of field values
*/
public final String[] getValues(String name) {
List<String> result = new ArrayList<>();
for (IndexableField field : fields) {
if (field.name().equals(name) && field.stringValue() != null) {
result.add(field.stringValue());
}
}
if (result.size() == 0) {
return NO_STRINGS;
}
return result.toArray(new String[result.size()]);
}
@Override
public String toExternal(IndexableField f) {
if (null != f.binaryValue()) {
return indexedToReadable(f.binaryValue().utf8ToString());
}
if (null != f.stringValue()) {
return indexedToReadable(f.stringValue());
}
return null;
}
@Override
public float score() throws IOException {
try {
final Document document = context.reader().document(itr.docID(),
fieldAsSet);
final IndexableField indexableField = document.getField(field);
if (indexableField == null) {
return getDefaultValue();
}
final Number number = indexableField.numericValue();
if (number != null) {
return number.floatValue();
} else {
final String string = indexableField.stringValue();
if (string.length() == 1) {
// boolean values in the index are encoded with the
// a single char contained in TRUE_TOKEN or FALSE_TOKEN
// (see BoolField)
if (string.charAt(0) == BoolField.TRUE_TOKEN[0]) {
return 1;
}
if (string.charAt(0) == BoolField.FALSE_TOKEN[0]) {
return 0;
}
}
}
} catch (final IOException e) {
throw new FeatureException(
e.toString() + ": " +
"Unable to extract feature for "
+ name, e);
}
return getDefaultValue();
}
protected String convertFieldValue(Object val) {
if (val instanceof IndexableField) {
IndexableField f = (IndexableField)val;
return f.stringValue();
}
return val.toString();
}
boolean isDirectChildAttribute(IndexableField child, IndexableField adult) {
String childId = child.stringValue();
String adultId = adult.stringValue();
String childPath = childId.substring(0, childId.lastIndexOf('.'));
String adultPath = adultId.substring(0, adultId.lastIndexOf('.'));
adultPath = adultPath.replaceFirst(":", ".");
String[] childSegments = child.stringValue().split("\\.");
String childType = childSegments[childSegments.length - 1];
return childPath.startsWith(adultPath + ":") && "attribute".equals(childType);
}
/**
* Convert the stored-field format to an external (string, human readable)
* value
* @see #toInternal
*/
public String toExternal(IndexableField f) {
// currently used in writing XML of the search result (but perhaps
// a more efficient toXML(IndexableField f, Writer w) should be used
// in the future.
String val = f.stringValue();
if (val == null) {
// docValues will use the binary value
val = f.binaryValue().utf8ToString();
}
return val;
}
private int buildElement(ArrayBackedValueStorage abvsFileNode, int fieldNum) throws SAXException {
int whereIFinish = fieldNum;
IndexableField field = fields.get(fieldNum);
String contents = field.stringValue();
String uri = "";
IndexAttributes atts = new IndexAttributes();
int firstColon = contents.indexOf(':');
int lastDot = contents.lastIndexOf('.');
String type = contents.substring(lastDot + 1);
String lastBit = contents.substring(firstColon + 1, lastDot);
int dots = contents.indexOf(".");
int nextdot;
String element = "";
int elements = 0;
if (this.firstElement) {
this.firstElement = false;
while (dots < firstColon) {
nextdot = dots;
dots = contents.indexOf(".", dots + 1);
element = contents.substring(nextdot + 1, dots);
if (dots > firstColon) {
element = contents.substring(nextdot + 1, firstColon);
}
atts.reset();
handler.startElement(uri, element, element, (Attributes) atts);
elements++;
}
}
if ("textnode".equals(type)) {
char[] charContents = lastBit.toCharArray();
handler.characters(charContents, 0, charContents.length);
}
if ("element".equals(type)) {
atts.reset();
whereIFinish = findAttributeChildren(whereIFinish, atts);
handler.startElement(uri, lastBit, lastBit, (Attributes) atts);
boolean noMoreChildren = false;
while (whereIFinish + 1 < fields.size() && !noMoreChildren) {
if (isChild(fields.get(whereIFinish + 1), field)) {
whereIFinish = buildElement(abvsFileNode, whereIFinish + 1);
} else {
noMoreChildren = true;
}
}
handler.endElement(uri, lastBit, lastBit);
}
while (elements > 0) {
handler.endElement(uri, element, element);
elements--;
}
return whereIFinish;
}
@Override
public List<NodeMetaData> getCascadeNodes(List<Long> txnIds) throws IOException, JSONException
{
List<FieldInstance> list = dataModel.getIndexedFieldNamesForProperty(ContentModel.PROP_CASCADE_TX).getFields();
FieldInstance fieldInstance = list.get(0);
RefCounted<SolrIndexSearcher> refCounted = null;
IntArrayList docList;
Set<Long> parentNodesId = new HashSet<>();
try
{
refCounted = core.getSearcher();
SolrIndexSearcher searcher = refCounted.get();
String field = fieldInstance.getField();
SchemaField schemaField = searcher.getSchema().getField(field);
FieldType fieldType = schemaField.getType();
BooleanQuery.Builder builder = new BooleanQuery.Builder();
BooleanQuery booleanQuery;
for(Long l : txnIds)
{
BytesRefBuilder bytesRefBuilder = new BytesRefBuilder();
fieldType.readableToIndexed(l.toString(), bytesRefBuilder);
TermQuery termQuery = new TermQuery(new Term(field, bytesRefBuilder.toBytesRef()));
BooleanClause booleanClause = new BooleanClause(termQuery, BooleanClause.Occur.SHOULD);
builder.add(booleanClause);
}
booleanQuery = builder.build();
DocListCollector collector = new DocListCollector();
searcher.search(booleanQuery, collector);
docList = collector.getDocs();
int size = docList.size();
for(int i=0; i<size; i++)
{
int docId = docList.get(i);
Document document = searcher.doc(docId, REQUEST_ONLY_ID_FIELD);
IndexableField indexableField = document.getField(FIELD_SOLR4_ID);
String id = indexableField.stringValue();
TenantDbId ids = AlfrescoSolrDataModel.decodeNodeDocumentId(id);
parentNodesId.add(ids.dbId);
}
}
finally
{
ofNullable(refCounted).ifPresent(RefCounted::decref);
}
List<NodeMetaData> allNodeMetaDatas = new ArrayList<>();
for (Long parentNodeId : parentNodesId)
{
NodeMetaDataParameters nmdp = new NodeMetaDataParameters();
nmdp.setFromNodeId(parentNodeId);
nmdp.setToNodeId(parentNodeId);
nmdp.setIncludeAclId(true);
nmdp.setIncludeChildAssociations(false);
nmdp.setIncludeChildIds(true);
nmdp.setIncludeOwner(false);
nmdp.setIncludeParentAssociations(false);
nmdp.setIncludePaths(true);
nmdp.setIncludeProperties(false);
nmdp.setIncludeTxnId(true);
nmdp.setMaxResults(1);
// Gets only one
Optional<Collection<NodeMetaData>> nodeMetaDatas = getNodesMetaDataFromRepository(nmdp);
allNodeMetaDatas.addAll(nodeMetaDatas.orElse(Collections.emptyList()));
}
return allNodeMetaDatas;
}
/**
* NOTE: This method will not preserve the correct field types.
*
* @param preTag
* @param postTag
*/
public static Document highlight(int docId, Document document, Query query, FieldManager fieldManager,
IndexReader reader, String preTag, String postTag) throws IOException, InvalidTokenOffsetsException {
String fieldLessFieldName = fieldManager.getFieldLessFieldName();
Query fixedQuery = fixSuperQuery(query, null, fieldLessFieldName);
Analyzer analyzer = fieldManager.getAnalyzerForQuery();
SimpleHTMLFormatter htmlFormatter = new SimpleHTMLFormatter(preTag, postTag);
Document result = new Document();
for (IndexableField f : document) {
String name = f.name();
if (fieldLessFieldName.equals(name) || FIELDS_NOT_TO_HIGHLIGHT.contains(name)) {
result.add(f);
continue;
}
String text = f.stringValue();
Number numericValue = f.numericValue();
Query fieldFixedQuery;
if (fieldManager.isFieldLessIndexed(name)) {
fieldFixedQuery = fixSuperQuery(query, name, fieldLessFieldName);
} else {
fieldFixedQuery = fixedQuery;
}
if (numericValue != null) {
if (shouldNumberBeHighlighted(name, numericValue, fieldFixedQuery)) {
String numberHighlight = preTag + text + postTag;
result.add(new StringField(name, numberHighlight, Store.YES));
}
} else {
Highlighter highlighter = new Highlighter(htmlFormatter, new QueryScorer(fieldFixedQuery, name));
TokenStream tokenStream = TokenSources.getAnyTokenStream(reader, docId, name, analyzer);
TextFragment[] frag = highlighter.getBestTextFragments(tokenStream, text, false, 10);
for (int j = 0; j < frag.length; j++) {
if ((frag[j] != null) && (frag[j].getScore() > 0)) {
result.add(new StringField(name, frag[j].toString(), Store.YES));
}
}
}
}
return result;
}
/**
* build a list of classification results from search results
* @param topDocs the search results as a {@link TopDocs} object
* @return a {@link List} of {@link ClassificationResult}, one for each existing class
* @throws IOException if it's not possible to get the stored value of class field
*/
protected List<ClassificationResult<BytesRef>> buildListFromTopDocs(TopDocs topDocs) throws IOException {
Map<BytesRef, Integer> classCounts = new HashMap<>();
Map<BytesRef, Double> classBoosts = new HashMap<>(); // this is a boost based on class ranking positions in topDocs
float maxScore = topDocs.totalHits.value == 0 ? Float.NaN : topDocs.scoreDocs[0].score;
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
IndexableField[] storableFields = indexSearcher.doc(scoreDoc.doc).getFields(classFieldName);
for (IndexableField singleStorableField : storableFields) {
if (singleStorableField != null) {
BytesRef cl = new BytesRef(singleStorableField.stringValue());
//update count
classCounts.merge(cl, 1, (a, b) -> a + b);
//update boost, the boost is based on the best score
Double totalBoost = classBoosts.get(cl);
double singleBoost = scoreDoc.score / maxScore;
if (totalBoost != null) {
classBoosts.put(cl, totalBoost + singleBoost);
} else {
classBoosts.put(cl, singleBoost);
}
}
}
}
List<ClassificationResult<BytesRef>> returnList = new ArrayList<>();
List<ClassificationResult<BytesRef>> temporaryList = new ArrayList<>();
int sumdoc = 0;
for (Map.Entry<BytesRef, Integer> entry : classCounts.entrySet()) {
Integer count = entry.getValue();
Double normBoost = classBoosts.get(entry.getKey()) / count; //the boost is normalized to be 0<b<1
temporaryList.add(new ClassificationResult<>(entry.getKey().clone(), (count * normBoost) / (double) k));
sumdoc += count;
}
//correction
if (sumdoc < k) {
for (ClassificationResult<BytesRef> cr : temporaryList) {
returnList.add(new ClassificationResult<>(cr.getAssignedClass(), cr.getScore() * k / (double) sumdoc));
}
} else {
returnList = temporaryList;
}
return returnList;
}
/**
* build a list of classification results from search results
*
* @param topDocs the search results as a {@link TopDocs} object
* @return a {@link List} of {@link ClassificationResult}, one for each existing class
* @throws IOException if it's not possible to get the stored value of class field
*/
private List<ClassificationResult<BytesRef>> buildListFromTopDocs(TopDocs topDocs) throws IOException {
Map<BytesRef, Integer> classCounts = new HashMap<>();
Map<BytesRef, Double> classBoosts = new HashMap<>(); // this is a boost based on class ranking positions in topDocs
float maxScore = topDocs.totalHits.value == 0 ? Float.NaN : topDocs.scoreDocs[0].score;
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
IndexableField storableField = indexSearcher.doc(scoreDoc.doc).getField(classFieldName);
if (storableField != null) {
BytesRef cl = new BytesRef(storableField.stringValue());
//update count
classCounts.merge(cl, 1, (a, b) -> a + b);
//update boost, the boost is based on the best score
Double totalBoost = classBoosts.get(cl);
double singleBoost = scoreDoc.score / maxScore;
if (totalBoost != null) {
classBoosts.put(cl, totalBoost + singleBoost);
} else {
classBoosts.put(cl, singleBoost);
}
}
}
List<ClassificationResult<BytesRef>> returnList = new ArrayList<>();
List<ClassificationResult<BytesRef>> temporaryList = new ArrayList<>();
int sumdoc = 0;
for (Map.Entry<BytesRef, Integer> entry : classCounts.entrySet()) {
Integer count = entry.getValue();
Double normBoost = classBoosts.get(entry.getKey()) / count; //the boost is normalized to be 0<b<1
temporaryList.add(new ClassificationResult<>(entry.getKey().clone(), (count * normBoost) / (double) k));
sumdoc += count;
}
//correction
if (sumdoc < k) {
for (ClassificationResult<BytesRef> cr : temporaryList) {
returnList.add(new ClassificationResult<>(cr.getAssignedClass(), cr.getScore() * k / (double) sumdoc));
}
} else {
returnList = temporaryList;
}
return returnList;
}
@Override
public void writeField(FieldInfo info, IndexableField field)
throws IOException {
++numStoredFieldsInDoc;
int bits = 0;
final BytesRef bytes;
final String string;
Number number = field.numericValue();
if (number != null) {
if (number instanceof Byte || number instanceof Short || number instanceof Integer) {
bits = NUMERIC_INT;
} else if (number instanceof Long) {
bits = NUMERIC_LONG;
} else if (number instanceof Float) {
bits = NUMERIC_FLOAT;
} else if (number instanceof Double) {
bits = NUMERIC_DOUBLE;
} else {
throw new IllegalArgumentException("cannot store numeric type " + number.getClass());
}
string = null;
bytes = null;
} else {
bytes = field.binaryValue();
if (bytes != null) {
bits = BYTE_ARR;
string = null;
} else {
bits = STRING;
string = field.stringValue();
if (string == null) {
throw new IllegalArgumentException("field " + field.name() + " is stored but does not have binaryValue, stringValue nor numericValue");
}
}
}
final long infoAndBits = (((long) info.number) << TYPE_BITS) | bits;
bufferedDocs.writeVLong(infoAndBits);
if (bytes != null) {
bufferedDocs.writeVInt(bytes.length);
bufferedDocs.writeBytes(bytes.bytes, bytes.offset, bytes.length);
} else if (string != null) {
bufferedDocs.writeString(string);
} else {
if (number instanceof Byte || number instanceof Short || number instanceof Integer) {
bufferedDocs.writeZInt(number.intValue());
} else if (number instanceof Long) {
writeTLong(bufferedDocs, number.longValue());
} else if (number instanceof Float) {
writeZFloat(bufferedDocs, number.floatValue());
} else if (number instanceof Double) {
writeZDouble(bufferedDocs, number.doubleValue());
} else {
throw new AssertionError("Cannot get here");
}
}
}
@Override
public Object get(IndexableField f) {
return f.stringValue();
}