Github user dsmiley commented on a diff in the pull request:
https://github.com/apache/lucene-solr/pull/416#discussion_r209069776
--- Diff:
solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java
---
@@ -70,109 +73,59 @@ public DocTransformer create(String field, SolrParams
params, SolrQueryRequest r
}
String parentFilter = params.get( "parentFilter" );
- if( parentFilter == null ) {
- throw new SolrException( ErrorCode.BAD_REQUEST, "Parent filter
should be sent as parentFilter=filterCondition" );
- }
-
- String childFilter = params.get( "childFilter" );
- int limit = params.getInt( "limit", 10 );
-
BitSetProducer parentsFilter = null;
- try {
- Query parentFilterQuery = QParser.getParser( parentFilter,
req).getQuery();
- //TODO shouldn't we try to use the Solr filter cache, and then
ideally implement
- // BitSetProducer over that?
- // DocSet parentDocSet =
req.getSearcher().getDocSet(parentFilterQuery);
- // then return BitSetProducer with custom BitSet impl accessing the
docSet
- parentsFilter = new QueryBitSetProducer(parentFilterQuery);
- } catch (SyntaxError syntaxError) {
- throw new SolrException( ErrorCode.BAD_REQUEST, "Failed to create
correct parent filter query" );
- }
-
- Query childFilterQuery = null;
- if(childFilter != null) {
+ boolean buildHierarchy = params.getBool("hierarchy", false);
+ if( parentFilter == null) {
+ if(!buildHierarchy) {
+ throw new SolrException( ErrorCode.BAD_REQUEST, "Parent filter
should be sent as parentFilter=filterCondition" );
+ }
+ parentsFilter = new QueryBitSetProducer(rootFilter);
+ } else {
try {
- childFilterQuery = QParser.getParser( childFilter, req).getQuery();
+ Query parentFilterQuery = QParser.getParser(parentFilter,
req).getQuery();
+ //TODO shouldn't we try to use the Solr filter cache, and then
ideally implement
+ // BitSetProducer over that?
+ // DocSet parentDocSet =
req.getSearcher().getDocSet(parentFilterQuery);
+ // then return BitSetProducer with custom BitSet impl accessing
the docSet
+ parentsFilter = new QueryBitSetProducer(parentFilterQuery);
} catch (SyntaxError syntaxError) {
- throw new SolrException( ErrorCode.BAD_REQUEST, "Failed to create
correct child filter query" );
+ throw new SolrException( ErrorCode.BAD_REQUEST, "Failed to create
correct parent filter query" );
}
}
- return new ChildDocTransformer( field, parentsFilter, uniqueKeyField,
req.getSchema(), childFilterQuery, limit);
- }
-}
-
-class ChildDocTransformer extends DocTransformer {
- private final String name;
- private final SchemaField idField;
- private final IndexSchema schema;
- private BitSetProducer parentsFilter;
- private Query childFilterQuery;
- private int limit;
-
- public ChildDocTransformer( String name, final BitSetProducer
parentsFilter,
- final SchemaField idField, IndexSchema
schema,
- final Query childFilterQuery, int limit) {
- this.name = name;
- this.idField = idField;
- this.schema = schema;
- this.parentsFilter = parentsFilter;
- this.childFilterQuery = childFilterQuery;
- this.limit = limit;
- }
+ String childFilter = params.get( "childFilter" );
+ int limit = params.getInt( "limit", 10 );
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public String[] getExtraRequestFields() {
- // we always need the idField (of the parent) in order to fill out
it's children
- return new String[] { idField.getName() };
+ if(buildHierarchy) {
+ if(childFilter != null) {
+ childFilter = buildHierarchyChildFilterString(childFilter);
+ return new ChildDocTransformer(field, parentsFilter, req,
+ getChildQuery(childFilter, req), limit);
+ }
+ return new ChildDocTransformer(field, parentsFilter, req, null,
limit);
+ }
+ return new ChildDocTransformer( field, parentsFilter, req,
+ childFilter==null? null: getChildQuery(childFilter, req), limit);
}
- @Override
- public void transform(SolrDocument doc, int docid) {
-
- FieldType idFt = idField.getType();
- Object parentIdField = doc.getFirstValue(idField.getName());
-
- String parentIdExt = parentIdField instanceof IndexableField
- ? idFt.toExternal((IndexableField)parentIdField)
- : parentIdField.toString();
-
+ private static Query getChildQuery(String childFilter, SolrQueryRequest
req) {
try {
- Query parentQuery = idFt.getFieldQuery(null, idField, parentIdExt);
- Query query = new ToChildBlockJoinQuery(parentQuery, parentsFilter);
- DocList children = context.getSearcher().getDocList(query,
childFilterQuery, new Sort(), 0, limit);
- if(children.matches() > 0) {
- SolrDocumentFetcher docFetcher =
context.getSearcher().getDocFetcher();
-
- Set<String> dvFieldsToReturn = docFetcher.getNonStoredDVs(true);
- boolean shouldDecorateWithDVs = dvFieldsToReturn.size() > 0;
- DocIterator i = children.iterator();
-
- while(i.hasNext()) {
- Integer childDocNum = i.next();
- Document childDoc = context.getSearcher().doc(childDocNum);
- // TODO: future enhancement...
- // support an fl local param in the transformer, which is used
to build
- // a private ReturnFields instance that we use to prune unwanted
field
- // names from solrChildDoc
- SolrDocument solrChildDoc =
DocsStreamer.convertLuceneDocToSolrDoc(childDoc, schema,
-
new SolrReturnFields());
+ return QParser.getParser( childFilter, req).getQuery();
+ } catch (SyntaxError syntaxError) {
+ throw new SolrException( ErrorCode.BAD_REQUEST, "Failed to create
correct child filter query" );
+ }
+ }
- if (shouldDecorateWithDVs) {
- docFetcher.decorateDocValueFields(solrChildDoc, childDocNum,
dvFieldsToReturn);
- }
- doc.addChildDocument(solrChildDoc);
- }
- }
-
- } catch (IOException e) {
- doc.put(name, "Could not fetch child Documents");
+ protected static String buildHierarchyChildFilterString(String
queryString) {
+ List<String> split = StrUtils.splitSmart(queryString, ':');
--- End diff --
FYI I've rewritten this method to not use splitting & joining in cases like
this which can use "indexOf"/"lastIndexOf". I've also increased it's
robustness to more complicated query examples of multiple conditions.
For now I think we shouldn't document this; let it be kinda a secret
feature until we can query (in q/fq) in like-kind.
---
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]