use of org.apache.solr.schema.SchemaField in project lucene-solr by apache.
the class SimpleMLTQParser method parse.
public Query parse() {
String defaultField = req.getSchema().getUniqueKeyField().getName();
String uniqueValue = localParams.get(QueryParsing.V);
String[] qf = localParams.getParams("qf");
SolrIndexSearcher searcher = req.getSearcher();
Query docIdQuery = createIdQuery(defaultField, uniqueValue);
Map<String, Float> boostFields = new HashMap<>();
try {
TopDocs td = searcher.search(docIdQuery, 1);
if (td.totalHits != 1)
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error completing MLT request. Could not fetch " + "document with id [" + uniqueValue + "]");
ScoreDoc[] scoreDocs = td.scoreDocs;
MoreLikeThis mlt = new MoreLikeThis(req.getSearcher().getIndexReader());
mlt.setMinTermFreq(localParams.getInt("mintf", MoreLikeThis.DEFAULT_MIN_TERM_FREQ));
mlt.setMinDocFreq(localParams.getInt("mindf", MoreLikeThis.DEFAULT_MIN_DOC_FREQ));
mlt.setMinWordLen(localParams.getInt("minwl", MoreLikeThis.DEFAULT_MIN_WORD_LENGTH));
mlt.setMaxWordLen(localParams.getInt("maxwl", MoreLikeThis.DEFAULT_MAX_WORD_LENGTH));
mlt.setMaxQueryTerms(localParams.getInt("maxqt", MoreLikeThis.DEFAULT_MAX_QUERY_TERMS));
mlt.setMaxNumTokensParsed(localParams.getInt("maxntp", MoreLikeThis.DEFAULT_MAX_NUM_TOKENS_PARSED));
mlt.setMaxDocFreq(localParams.getInt("maxdf", MoreLikeThis.DEFAULT_MAX_DOC_FREQ));
Boolean boost = localParams.getBool("boost", false);
mlt.setBoost(boost);
String[] fieldNames;
if (qf != null) {
ArrayList<String> fields = new ArrayList<>();
for (String fieldName : qf) {
if (!StringUtils.isEmpty(fieldName)) {
String[] strings = splitList.split(fieldName);
for (String string : strings) {
if (!StringUtils.isEmpty(string)) {
fields.add(string);
}
}
}
}
// Parse field names and boosts from the fields
boostFields = SolrPluginUtils.parseFieldBoosts(fields.toArray(new String[0]));
fieldNames = boostFields.keySet().toArray(new String[0]);
} else {
Map<String, SchemaField> fieldDefinitions = req.getSearcher().getSchema().getFields();
ArrayList<String> fields = new ArrayList();
for (String fieldName : fieldDefinitions.keySet()) {
if (fieldDefinitions.get(fieldName).indexed() && fieldDefinitions.get(fieldName).stored())
if (fieldDefinitions.get(fieldName).getType().getNumberType() == null)
fields.add(fieldName);
}
fieldNames = fields.toArray(new String[0]);
}
if (fieldNames.length < 1) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "MoreLikeThis requires at least one similarity field: qf");
}
mlt.setFieldNames(fieldNames);
mlt.setAnalyzer(req.getSchema().getIndexAnalyzer());
Query rawMLTQuery = mlt.like(scoreDocs[0].doc);
BooleanQuery boostedMLTQuery = (BooleanQuery) rawMLTQuery;
if (boost && boostFields.size() > 0) {
BooleanQuery.Builder newQ = new BooleanQuery.Builder();
newQ.setMinimumNumberShouldMatch(boostedMLTQuery.getMinimumNumberShouldMatch());
for (BooleanClause clause : boostedMLTQuery) {
Query q = clause.getQuery();
float originalBoost = 1f;
if (q instanceof BoostQuery) {
BoostQuery bq = (BoostQuery) q;
q = bq.getQuery();
originalBoost = bq.getBoost();
}
Float fieldBoost = boostFields.get(((TermQuery) q).getTerm().field());
q = ((fieldBoost != null) ? new BoostQuery(q, fieldBoost * originalBoost) : clause.getQuery());
newQ.add(q, clause.getOccur());
}
boostedMLTQuery = newQ.build();
}
// exclude current document from results
BooleanQuery.Builder realMLTQuery = new BooleanQuery.Builder();
realMLTQuery.add(boostedMLTQuery, BooleanClause.Occur.MUST);
realMLTQuery.add(docIdQuery, BooleanClause.Occur.MUST_NOT);
return realMLTQuery.build();
} catch (IOException e) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error completing MLT request" + e.getMessage());
}
}
use of org.apache.solr.schema.SchemaField in project lucene-solr by apache.
the class ChildFieldValueSourceParser method parse.
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
final String sortFieldName = fp.parseArg();
final Query query;
if (fp.hasMoreArguments()) {
query = fp.parseNestedQuery();
} else {
query = fp.subQuery(fp.getParam(CommonParams.Q), BlockJoinParentQParserPlugin.NAME).getQuery();
}
BitSetProducer parentFilter;
BitSetProducer childFilter;
SchemaField sf;
try {
AllParentsAware bjQ;
if (!(query instanceof AllParentsAware)) {
throw new SyntaxError("expect a reference to block join query " + AllParentsAware.class.getSimpleName() + " in " + fp.getString());
}
bjQ = (AllParentsAware) query;
parentFilter = BlockJoinParentQParser.getCachedFilter(fp.getReq(), bjQ.getParentQuery()).filter;
childFilter = BlockJoinParentQParser.getCachedFilter(fp.getReq(), bjQ.getChildQuery()).filter;
if (sortFieldName == null || sortFieldName.equals("")) {
throw new SyntaxError("field is omitted in " + fp.getString());
}
sf = fp.getReq().getSchema().getFieldOrNull(sortFieldName);
if (null == sf) {
throw new SyntaxError(NAME + " sort param field \"" + sortFieldName + "\" can't be found in schema");
}
} catch (SyntaxError e) {
log.error("can't parse " + fp.getString(), e);
throw e;
}
return new BlockJoinSortFieldValueSource(childFilter, parentFilter, sf);
}
use of org.apache.solr.schema.SchemaField in project lucene-solr by apache.
the class AtomicUpdateDocumentMerger method doInc.
protected void doInc(SolrInputDocument toDoc, SolrInputField sif, Object fieldVal) {
SolrInputField numericField = toDoc.get(sif.getName());
SchemaField sf = schema.getField(sif.getName());
if (numericField != null || sf.getDefaultValue() != null) {
// TODO: fieldtype needs externalToObject?
String oldValS = (numericField != null) ? numericField.getFirstValue().toString() : sf.getDefaultValue().toString();
BytesRefBuilder term = new BytesRefBuilder();
sf.getType().readableToIndexed(oldValS, term);
Object oldVal = sf.getType().toObject(sf, term.get());
String fieldValS = fieldVal.toString();
Number result;
if (oldVal instanceof Long) {
result = ((Long) oldVal).longValue() + Long.parseLong(fieldValS);
} else if (oldVal instanceof Float) {
result = ((Float) oldVal).floatValue() + Float.parseFloat(fieldValS);
} else if (oldVal instanceof Double) {
result = ((Double) oldVal).doubleValue() + Double.parseDouble(fieldValS);
} else {
// int, short, byte
result = ((Integer) oldVal).intValue() + Integer.parseInt(fieldValS);
}
toDoc.setField(sif.getName(), result);
} else {
toDoc.setField(sif.getName(), fieldVal);
}
}
use of org.apache.solr.schema.SchemaField in project lucene-solr by apache.
the class AtomicUpdateDocumentMerger method doInPlaceUpdateMerge.
/**
* Given an AddUpdateCommand containing update operations (e.g. set, inc), merge and resolve the operations into
* a partial document that can be used for indexing the in-place updates. The AddUpdateCommand is modified to contain
* the partial document (instead of the original document which contained the update operations) and also
* the prevVersion that this in-place update depends on.
* Note: updatedFields passed into the method can be changed, i.e. the version field can be added to the set.
* @return If in-place update cannot succeed, e.g. if the old document is deleted recently, then false is returned. A false
* return indicates that this update can be re-tried as a full atomic update. Returns true if the in-place update
* succeeds.
*/
public boolean doInPlaceUpdateMerge(AddUpdateCommand cmd, Set<String> updatedFields) throws IOException {
SolrInputDocument inputDoc = cmd.getSolrInputDocument();
BytesRef idBytes = cmd.getIndexedId();
// add the version field so that it is fetched too
updatedFields.add(CommonParams.VERSION_FIELD);
SolrInputDocument oldDocument = RealTimeGetComponent.getInputDocument(cmd.getReq().getCore(), idBytes, // don't want the version to be returned
null, // avoid stored fields from index
true, updatedFields, // resolve the full document
true);
if (oldDocument == RealTimeGetComponent.DELETED || oldDocument == null) {
// This doc was deleted recently. In-place update cannot work, hence a full atomic update should be tried.
return false;
}
if (oldDocument.containsKey(CommonParams.VERSION_FIELD) == false) {
throw new SolrException(ErrorCode.INVALID_STATE, "There is no _version_ in previous document. id=" + cmd.getPrintableId());
}
Long oldVersion = (Long) oldDocument.remove(CommonParams.VERSION_FIELD).getValue();
// fetched from the tlog and had all these fields (possibly because it was a full document ADD operation).
if (updatedFields != null) {
Collection<String> names = new HashSet<String>(oldDocument.getFieldNames());
for (String fieldName : names) {
if (fieldName.equals(CommonParams.VERSION_FIELD) == false && fieldName.equals(ID) == false && updatedFields.contains(fieldName) == false) {
oldDocument.remove(fieldName);
}
}
}
// Copy over all supported DVs from oldDocument to partialDoc
//
// Assuming multiple updates to the same doc: field 'dv1' in one update, then field 'dv2' in a second
// update, and then again 'dv1' in a third update (without commits in between), the last update would
// fetch from the tlog the partial doc for the 2nd (dv2) update. If that doc doesn't copy over the
// previous updates to dv1 as well, then a full resolution (by following previous pointers) would
// need to be done to calculate the dv1 value -- so instead copy all the potentially affected DV fields.
SolrInputDocument partialDoc = new SolrInputDocument();
String uniqueKeyField = schema.getUniqueKeyField().getName();
for (String fieldName : oldDocument.getFieldNames()) {
SchemaField schemaField = schema.getField(fieldName);
if (fieldName.equals(uniqueKeyField) || isSupportedFieldForInPlaceUpdate(schemaField)) {
partialDoc.addField(fieldName, oldDocument.getFieldValue(fieldName));
}
}
merge(inputDoc, partialDoc);
// Populate the id field if not already populated (this can happen since stored fields were avoided during fetch from RTGC)
if (!partialDoc.containsKey(schema.getUniqueKeyField().getName())) {
partialDoc.addField(idField.getName(), inputDoc.getField(schema.getUniqueKeyField().getName()).getFirstValue());
}
cmd.prevVersion = oldVersion;
cmd.solrDoc = partialDoc;
return true;
}
use of org.apache.solr.schema.SchemaField in project lucene-solr by apache.
the class PreAnalyzedUpdateProcessor method mutate.
@Override
protected SolrInputField mutate(SolrInputField src) {
SchemaField sf = schema.getFieldOrNull(src.getName());
if (sf == null) {
// remove this field
return null;
}
FieldType type = PreAnalyzedField.createFieldType(sf);
if (type == null) {
// neither indexed nor stored - skip
return null;
}
SolrInputField res = new SolrInputField(src.getName());
for (Object o : src) {
if (o == null) {
continue;
}
Field pre = (Field) parser.createField(sf, o);
if (pre != null) {
res.addValue(pre);
} else {
// restore the original value
log.warn("Could not parse field {} - using original value as is: {}", src.getName(), o);
res.addValue(o);
}
}
return res;
}
Aggregations