Port MultiFieldQueryParser Contrib.QueryParsers.Classic now complete
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/04944ede Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/04944ede Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/04944ede Branch: refs/heads/branch_4x Commit: 04944ede8e62e89e4a498c7bf4462b9b7bef15ad Parents: 3c5bf26 Author: Paul Irwin <[email protected]> Authored: Thu Oct 3 12:22:01 2013 -0400 Committer: Paul Irwin <[email protected]> Committed: Sat Oct 5 16:37:24 2013 -0400 ---------------------------------------------------------------------- .../Classic/MultiFieldQueryParser.cs | 229 +++++++++++++++++++ .../QueryParsers/Classic/QueryParserBase.cs | 18 +- .../QueryParsers/Contrib.QueryParsers.csproj | 1 + 3 files changed, 237 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucenenet/blob/04944ede/src/contrib/QueryParsers/Classic/MultiFieldQueryParser.cs ---------------------------------------------------------------------- diff --git a/src/contrib/QueryParsers/Classic/MultiFieldQueryParser.cs b/src/contrib/QueryParsers/Classic/MultiFieldQueryParser.cs new file mode 100644 index 0000000..4d38c28 --- /dev/null +++ b/src/contrib/QueryParsers/Classic/MultiFieldQueryParser.cs @@ -0,0 +1,229 @@ +using Lucene.Net.Analysis; +using Lucene.Net.Search; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Version = Lucene.Net.Util.Version; + +namespace Lucene.Net.QueryParsers.Classic +{ + public class MultiFieldQueryParser : QueryParser + { + protected string[] fields; + protected IDictionary<string, float> boosts; + + public MultiFieldQueryParser(Version matchVersion, string[] fields, Analyzer analyzer, IDictionary<string, float> boosts) + : this(matchVersion, fields, analyzer) + { + this.boosts = boosts; + } + + public MultiFieldQueryParser(Version matchVersion, string[] fields, Analyzer analyzer) + : base(matchVersion, null, analyzer) + { + this.fields = fields; + } + + protected override Query GetFieldQuery(string field, string queryText, int slop) + { + if (field == null) + { + IList<BooleanClause> clauses = new List<BooleanClause>(); + for (int i = 0; i < fields.Length; i++) + { + Query q = base.GetFieldQuery(fields[i], queryText, true); + if (q != null) + { + //If the user passes a map of boosts + if (boosts != null) + { + //Get the boost from the map and apply them + float boost; + if (boosts.TryGetValue(fields[i], out boost)) + { + q.Boost = boost; + } + } + ApplySlop(q, slop); + clauses.Add(new BooleanClause(q, Occur.SHOULD)); + } + } + if (clauses.Count == 0) // happens for stopwords + return null; + return GetBooleanQuery(clauses, true); + } + Query q2 = base.GetFieldQuery(field, queryText, true); + ApplySlop(q2, slop); + return q2; + } + + private void ApplySlop(Query q, int slop) + { + if (q is PhraseQuery) + { + ((PhraseQuery)q).Slop = slop; + } + else if (q is MultiPhraseQuery) + { + ((MultiPhraseQuery)q).Slop = slop; + } + } + + protected override Query GetFieldQuery(string field, string queryText, bool quoted) + { + if (field == null) + { + IList<BooleanClause> clauses = new List<BooleanClause>(); + for (int i = 0; i < fields.Length; i++) + { + Query q = base.GetFieldQuery(fields[i], queryText, quoted); + if (q != null) + { + //If the user passes a map of boosts + if (boosts != null) + { + //Get the boost from the map and apply them + float boost; + if (boosts.TryGetValue(fields[i], out boost)) + { + q.Boost = boost; + } + } + clauses.Add(new BooleanClause(q, Occur.SHOULD)); + } + } + if (clauses.Count == 0) // happens for stopwords + return null; + return GetBooleanQuery(clauses, true); + } + Query q2 = base.GetFieldQuery(field, queryText, quoted); + return q2; + } + + protected override Query GetFuzzyQuery(string field, string termStr, float minSimilarity) + { + if (field == null) + { + IList<BooleanClause> clauses = new List<BooleanClause>(); + for (int i = 0; i < fields.Length; i++) + { + clauses.Add(new BooleanClause(GetFuzzyQuery(fields[i], termStr, minSimilarity), Occur.SHOULD)); + } + return GetBooleanQuery(clauses, true); + } + return base.GetFuzzyQuery(field, termStr, minSimilarity); + } + + protected override Query GetPrefixQuery(string field, string termStr) + { + if (field == null) + { + IList<BooleanClause> clauses = new List<BooleanClause>(); + for (int i = 0; i < fields.Length; i++) + { + clauses.Add(new BooleanClause(GetPrefixQuery(fields[i], termStr), Occur.SHOULD)); + } + return GetBooleanQuery(clauses, true); + } + return base.GetPrefixQuery(field, termStr); + } + + protected override Query GetWildcardQuery(string field, string termStr) + { + if (field == null) + { + IList<BooleanClause> clauses = new List<BooleanClause>(); + for (int i = 0; i < fields.Length; i++) + { + clauses.Add(new BooleanClause(GetWildcardQuery(fields[i], termStr), Occur.SHOULD)); + } + return GetBooleanQuery(clauses, true); + } + return base.GetWildcardQuery(field, termStr); + } + + protected override Query GetRangeQuery(string field, string part1, string part2, bool startInclusive, bool endInclusive) + { + if (field == null) + { + IList<BooleanClause> clauses = new List<BooleanClause>(); + for (int i = 0; i < fields.Length; i++) + { + clauses.Add(new BooleanClause(GetRangeQuery(fields[i], part1, part2, startInclusive, endInclusive), Occur.SHOULD)); + } + return GetBooleanQuery(clauses, true); + } + return base.GetRangeQuery(field, part1, part2, startInclusive, endInclusive); + } + + protected override Query GetRegexpQuery(string field, string termStr) + { + if (field == null) + { + IList<BooleanClause> clauses = new List<BooleanClause>(); + for (int i = 0; i < fields.Length; i++) + { + clauses.Add(new BooleanClause(GetRegexpQuery(fields[i], termStr), Occur.SHOULD)); + } + return GetBooleanQuery(clauses, true); + } + return base.GetRegexpQuery(field, termStr); + } + + public static Query Parse(Version matchVersion, string[] queries, string[] fields, Analyzer analyzer) + { + if (queries.Length != fields.Length) + throw new ArgumentException("queries.length != fields.length"); + BooleanQuery bQuery = new BooleanQuery(); + for (int i = 0; i < fields.Length; i++) + { + QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer); + Query q = qp.Parse(queries[i]); + if (q != null && // q never null, just being defensive + (!(q is BooleanQuery) || ((BooleanQuery)q).Clauses.Length > 0)) + { + bQuery.Add(q, Occur.SHOULD); + } + } + return bQuery; + } + + public static Query Parse(Version matchVersion, string query, string[] fields, Occur[] flags, Analyzer analyzer) + { + if (fields.Length != flags.Length) + throw new ArgumentException("fields.length != flags.length"); + BooleanQuery bQuery = new BooleanQuery(); + for (int i = 0; i < fields.Length; i++) + { + QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer); + Query q = qp.Parse(query); + if (q != null && // q never null, just being defensive + (!(q is BooleanQuery) || ((BooleanQuery)q).Clauses.Length > 0)) + { + bQuery.Add(q, flags[i]); + } + } + return bQuery; + } + + public static Query Parse(Version matchVersion, string[] queries, string[] fields, Occur[] flags, Analyzer analyzer) + { + if (!(queries.Length == fields.Length && queries.Length == flags.Length)) + throw new ArgumentException("queries, fields, and flags array have have different length"); + BooleanQuery bQuery = new BooleanQuery(); + for (int i = 0; i < fields.Length; i++) + { + QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer); + Query q = qp.Parse(queries[i]); + if (q != null && // q never null, just being defensive + (!(q is BooleanQuery) || ((BooleanQuery)q).Clauses.Length > 0)) + { + bQuery.Add(q, flags[i]); + } + } + return bQuery; + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/04944ede/src/contrib/QueryParsers/Classic/QueryParserBase.cs ---------------------------------------------------------------------- diff --git a/src/contrib/QueryParsers/Classic/QueryParserBase.cs b/src/contrib/QueryParsers/Classic/QueryParserBase.cs index 5425f0c..7e0a9fb 100644 --- a/src/contrib/QueryParsers/Classic/QueryParserBase.cs +++ b/src/contrib/QueryParsers/Classic/QueryParserBase.cs @@ -299,7 +299,7 @@ namespace Lucene.Net.QueryParsers.Classic throw new SystemException("Clause cannot be both required and prohibited"); } - protected Query GetFieldQuery(String field, String queryText, bool quoted) + protected virtual Query GetFieldQuery(String field, String queryText, bool quoted) { return NewFieldQuery(analyzer, field, queryText, quoted); } @@ -559,7 +559,7 @@ namespace Lucene.Net.QueryParsers.Classic } } - protected Query GetFieldQuery(String field, String queryText, int slop) + protected virtual Query GetFieldQuery(String field, String queryText, int slop) { Query query = GetFieldQuery(field, queryText, true); @@ -575,11 +575,7 @@ namespace Lucene.Net.QueryParsers.Classic return query; } - protected Query GetRangeQuery(String field, - String part1, - String part2, - bool startInclusive, - bool endInclusive) + protected virtual Query GetRangeQuery(String field, String part1, String part2, bool startInclusive, bool endInclusive) { if (lowercaseExpandedTerms) { @@ -778,7 +774,7 @@ namespace Lucene.Net.QueryParsers.Classic return query; } - protected Query GetWildcardQuery(String field, String termStr) + protected virtual Query GetWildcardQuery(String field, String termStr) { if ("*".Equals(field)) { @@ -794,7 +790,7 @@ namespace Lucene.Net.QueryParsers.Classic return NewWildcardQuery(t); } - protected Query GetRegexpQuery(String field, String termStr) + protected virtual Query GetRegexpQuery(String field, String termStr) { if (lowercaseExpandedTerms) { @@ -804,7 +800,7 @@ namespace Lucene.Net.QueryParsers.Classic return NewRegexpQuery(t); } - protected Query GetPrefixQuery(String field, String termStr) + protected virtual Query GetPrefixQuery(String field, String termStr) { if (!allowLeadingWildcard && termStr.StartsWith("*")) throw new ParseException("'*' not allowed as first character in PrefixQuery"); @@ -816,7 +812,7 @@ namespace Lucene.Net.QueryParsers.Classic return NewPrefixQuery(t); } - protected Query GetFuzzyQuery(String field, String termStr, float minSimilarity) + protected virtual Query GetFuzzyQuery(String field, String termStr, float minSimilarity) { if (lowercaseExpandedTerms) { http://git-wip-us.apache.org/repos/asf/lucenenet/blob/04944ede/src/contrib/QueryParsers/Contrib.QueryParsers.csproj ---------------------------------------------------------------------- diff --git a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj index 7cb9b2d..6ca31a9 100644 --- a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj +++ b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj @@ -42,6 +42,7 @@ <ItemGroup> <Compile Include="Classic\FastCharStream.cs" /> <Compile Include="Classic\ICharStream.cs" /> + <Compile Include="Classic\MultiFieldQueryParser.cs" /> <Compile Include="Classic\QueryParserConstants.cs" /> <Compile Include="Classic\ParseException.cs" /> <Compile Include="Classic\QueryParser.cs" />
