> > It looks like things have changed a bit since this subject was last > > brought > > up here. I see that there are support in Solr/Lucene for indexing > > payload > > data (DelimitedPayloadTokenFilterFactory and > > DelimitedPayloadTokenFilter). > > Overriding the Similarity class is straight forward. So the last > > piece of > > the puzzle is to use a BoostingTermQuery when searching. I think > > all I need > > to do is to subclass Solr's LuceneQParserPlugin uses SolrQueryParser > > under > > the cover. I think all I need to do is to write my own query parser > > plugin > > that uses a custom query parser, with the only difference being in > the > > getFieldQuery() method where a BoostingTermQuery is used instead of a > > TermQuery. > > The BTQ is now deprecated in favor of the BoostingFunctionTermQuery, > which gives some more flexibility in terms of how the spans in a > single document are scored. > > > > > Am I on the right track? > > Yes. > > > Has anyone done something like this already? >
I wrote a QParserPlugin that seems to do the trick. This is minimally tested - we're not actually using it at the moment, but should get you going. Also, as Grant suggested, you may want to sub BFTQ for BTQ below: package com.zoominfo.solr.analysis; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.Term; import org.apache.lucene.queryParser.*; import org.apache.lucene.search.*; import org.apache.lucene.search.payloads.BoostingTermQuery; import org.apache.solr.common.params.*; import org.apache.solr.common.util.NamedList; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.search.*; public class BoostingTermQParserPlugin extends QParserPlugin { public static String NAME = "zoom"; public void init(NamedList args) { } public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) { System.out.print("BoostingTermQParserPlugin::createParser\n"); return new BoostingTermQParser(qstr, localParams, params, req); } } class BoostingTermQueryParser extends QueryParser { public BoostingTermQueryParser(String f, Analyzer a) { super(f, a); System.out.print("BoostingTermQueryParser::BoostingTermQueryParser\n"); } @Override protected Query newTermQuery(Term term){ System.out.print("BoostingTermQueryParser::newTermQuery\n"); return new BoostingTermQuery(term); } } class BoostingTermQParser extends QParser { String sortStr; QueryParser lparser; public BoostingTermQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) { super(qstr, localParams, params, req); System.out.print("BoostingTermQParser::BoostingTermQParser\n"); } public Query parse() throws ParseException { System.out.print("BoostingTermQParser::parse\n"); String qstr = getString(); String defaultField = getParam(CommonParams.DF); if (defaultField==null) { defaultField = getReq().getSchema().getSolrQueryParser(null).getField(); } lparser = new BoostingTermQueryParser(defaultField, getReq().getSchema().getQueryAnalyzer()); // these could either be checked & set here, or in the SolrQueryParser constructor String opParam = getParam(QueryParsing.OP); if (opParam != null) { lparser.setDefaultOperator("AND".equals(opParam) ? QueryParser.Operator.AND : QueryParser.Operator.OR); } else { // try to get default operator from schema lparser.setDefaultOperator(getReq().getSchema().getSolrQueryParser(null).getDefaultOperator()); } return lparser.parse(qstr); } public String[] getDefaultHighlightFields() { return new String[]{lparser.getField()}; } }