From 284ff5235da2e0b9325fa2720bcf053f8e89a51c Mon Sep 17 00:00:00 2001 From: Christine Poerschke Date: Tue, 12 Jan 2016 17:49:28 +0000 Subject: [PATCH] SOLR-839: XML QueryParser support (deftype=xmlparser) git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1724293 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 17 +++++ solr/common-build.xml | 6 ++ solr/core/build.xml | 3 +- .../org/apache/solr/search/QParserPlugin.java | 3 +- .../apache/solr/search/SolrCoreParser.java | 39 ++++++++++ .../apache/solr/search/XmlQParserPlugin.java | 74 +++++++++++++++++++ .../apache/solr/search/QueryEqualityTest.java | 8 ++ .../apache/solr/search/TestXmlQParser.java | 43 +++++++++++ 8 files changed, 191 insertions(+), 2 deletions(-) create mode 100755 solr/core/src/java/org/apache/solr/search/SolrCoreParser.java create mode 100755 solr/core/src/java/org/apache/solr/search/XmlQParserPlugin.java create mode 100755 solr/core/src/test/org/apache/solr/search/TestXmlQParser.java diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 9a10cd7b390..4db9391dfa1 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -290,6 +290,23 @@ New Features * SOLR-8477: Let users choose compression mode in SchemaCodecFactory (Tomás Fernández Löbbe) +* SOLR-839: XML QueryParser support (defType=xmlparser) + Lucene includes a queryparser that supports the creation of Lucene queries from XML. + The queries supported by lucene.queryparser.xml.CoreParser are now supported by the newly + created solr.search.SolrCoreParser and in future SolrCoreParser could support additional + queries also. + Example: + shirt + plain + cotton + + + S M L + + + + (Erik Hatcher, Karl Wettin, Daniel Collins, Nathan Visagan, Christine Poerschke) + Bug Fixes ---------------------- diff --git a/solr/common-build.xml b/solr/common-build.xml index ca4ae3de5f8..7d3f0b6a0eb 100644 --- a/solr/common-build.xml +++ b/solr/common-build.xml @@ -461,6 +461,12 @@ + + + + + + diff --git a/solr/core/build.xml b/solr/core/build.xml index dd9d07fa781..b3a654ee8c8 100644 --- a/solr/core/build.xml +++ b/solr/core/build.xml @@ -31,13 +31,14 @@ - + + diff --git a/solr/core/src/java/org/apache/solr/search/QParserPlugin.java b/solr/core/src/java/org/apache/solr/search/QParserPlugin.java index 63859f891e2..3a38c4cd91e 100644 --- a/solr/core/src/java/org/apache/solr/search/QParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/QParserPlugin.java @@ -45,7 +45,7 @@ public abstract class QParserPlugin implements NamedListInitializedPlugin, SolrI public static final Map> standardPlugins; static { - HashMap> map = new HashMap<>(29, 1); + HashMap> map = new HashMap<>(30, 1); map.put(LuceneQParserPlugin.NAME, LuceneQParserPlugin.class); map.put(OldLuceneQParserPlugin.NAME, OldLuceneQParserPlugin.class); map.put(FunctionQParserPlugin.NAME, FunctionQParserPlugin.class); @@ -75,6 +75,7 @@ public abstract class QParserPlugin implements NamedListInitializedPlugin, SolrI map.put(MLTQParserPlugin.NAME, MLTQParserPlugin.class); map.put(HashQParserPlugin.NAME, HashQParserPlugin.class); map.put(GraphQParserPlugin.NAME, GraphQParserPlugin.class); + map.put(XmlQParserPlugin.NAME, XmlQParserPlugin.class); standardPlugins = Collections.unmodifiableMap(map); } diff --git a/solr/core/src/java/org/apache/solr/search/SolrCoreParser.java b/solr/core/src/java/org/apache/solr/search/SolrCoreParser.java new file mode 100755 index 00000000000..8d54beb8c79 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/search/SolrCoreParser.java @@ -0,0 +1,39 @@ +package org.apache.solr.search; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.queryparser.xml.CoreParser; + +import org.apache.solr.request.SolrQueryRequest; + +/** + * Assembles a QueryBuilder which uses Query objects from Solr's search module + * in addition to Query objects supported by the Lucene CoreParser. + */ +public class SolrCoreParser extends CoreParser { + + public SolrCoreParser(String defaultField, Analyzer analyzer, + SolrQueryRequest req) { + super(defaultField, analyzer); + + // final IndexSchema schema = req.getSchema(); + // lucene_parser.addQueryBuilder("SomeOtherQuery", new SomeOtherQueryBuilder(schema)); + } + +} diff --git a/solr/core/src/java/org/apache/solr/search/XmlQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/XmlQParserPlugin.java new file mode 100755 index 00000000000..d260996289f --- /dev/null +++ b/solr/core/src/java/org/apache/solr/search/XmlQParserPlugin.java @@ -0,0 +1,74 @@ +package org.apache.solr.search; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.ByteArrayInputStream; +import java.io.UnsupportedEncodingException; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.queryparser.xml.ParserException; +import org.apache.lucene.search.Query; + +import org.apache.solr.common.params.CommonParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.schema.IndexSchema; + +public class XmlQParserPlugin extends QParserPlugin { + public static final String NAME = "xmlparser"; + + private class XmlQParser extends QParser { + + private final String contentEncoding = "UTF8"; + + public XmlQParser(String qstr, SolrParams localParams, + SolrParams params, SolrQueryRequest req) { + super(qstr, localParams, params, req); + } + + public Query parse() throws SyntaxError { + final String qstr = getString(); + if (qstr == null || qstr.isEmpty()) { + return null; + } + final IndexSchema schema = req.getSchema(); + final String defaultField = QueryParsing.getDefaultField(schema, getParam(CommonParams.DF)); + final Analyzer analyzer = schema.getQueryAnalyzer(); + final SolrCoreParser solrParser = new SolrCoreParser(defaultField, analyzer, req); + try { + return solrParser.parse(new ByteArrayInputStream(qstr.getBytes(contentEncoding))); + } catch (UnsupportedEncodingException e) { + throw new SyntaxError(e.getMessage() + " in " + req.toString()); + } catch (ParserException e) { + throw new SyntaxError(e.getMessage() + " in " + req.toString()); + } + } + + } + + @Override + public void init(NamedList args) { + } + + public QParser createParser(String qstr, SolrParams localParams, + SolrParams params, SolrQueryRequest req) { + return new XmlQParser(qstr, localParams, params, req); + } + +} diff --git a/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java b/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java index 6ab43e9e93f..249ac3df465 100644 --- a/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java +++ b/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java @@ -190,6 +190,14 @@ public class QueryEqualityTest extends SolrTestCaseJ4 { } } + public void testMatchAllDocsQueryXmlParser() throws Exception { + final String type = "xmlparser"; + assertQueryEquals(type, + "{!"+type+"}", + "", + ""); + } + public void testQueryDismax() throws Exception { for (final String type : new String[]{"dismax","edismax"}) { assertQueryEquals(type, "{!"+type+"}apache solr", diff --git a/solr/core/src/test/org/apache/solr/search/TestXmlQParser.java b/solr/core/src/test/org/apache/solr/search/TestXmlQParser.java new file mode 100755 index 00000000000..847b47d9e23 --- /dev/null +++ b/solr/core/src/test/org/apache/solr/search/TestXmlQParser.java @@ -0,0 +1,43 @@ +package org.apache.solr.search; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.lucene.queryparser.xml.CoreParser; +import org.apache.lucene.queryparser.xml.TestCoreParser; + +public class TestXmlQParser extends TestCoreParser { + + private CoreParser solrCoreParser; + + @Override + protected CoreParser coreParser() { + if (solrCoreParser == null) { + solrCoreParser = new SolrCoreParser( + super.defaultField(), + super.analyzer(), + null); + } + return solrCoreParser; + } + + //public void testSomeOtherQuery() { + // Query q = parse("SomeOtherQuery.xml"); + // dumpResults("SomeOtherQuery", q, ?); + //} + +}