public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query) { if (type != "terms") { return(null); } var first = query.Properties().First(); var field = first.Name; var boolQuery = new BooleanQuery(); switch (first.Value.Type) { case JTokenType.Array: foreach (var item in ((JArray)first.Value)) { if (item.Type != JTokenType.String) { throw new ArgumentException($"Invalid term in terms query"); } boolQuery.Add(new TermQuery(new Term(field, item.Value <string>())), Occur.SHOULD); } break; case JTokenType.Object: throw new ArgumentException("The terms lookup query is not supported"); default: throw new ArgumentException("Invalid terms query"); } return(boolQuery); }
public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query) { if (type != "regexp") { return(null); } var first = query.Properties().First(); switch (first.Value.Type) { case JTokenType.String: return(new RegexpQuery(new Term(first.Name, first.Value.ToString()))); case JTokenType.Object: var obj = (JObject)first.Value; if (!obj.TryGetValue("value", out var value)) { throw new ArgumentException("Missing value in regexp query"); } // TODO: Support flags var regexpQuery = new RegexpQuery(new Term(value.Value <string>())); if (obj.TryGetValue("boost", out var boost)) { regexpQuery.Boost = boost.Value <float>(); } return(regexpQuery); default: throw new ArgumentException("Invalid regexp query"); } }
public AdminController( ISession session, IContentManager contentManager, IContentDefinitionManager contentDefinitionManager, LuceneIndexManager luceneIndexManager, LuceneIndexingService luceneIndexingService, IAuthorizationService authorizationService, LuceneAnalyzerManager luceneAnalyzerManager, LuceneIndexSettingsService luceneIndexSettingsService, ILuceneQueryService queryService, ILiquidTemplateManager liquidTemplateManager, INotifier notifier, ISiteService siteService, IShapeFactory shapeFactory, IStringLocalizer <AdminController> s, IHtmlLocalizer <AdminController> h, ILogger <AdminController> logger) { _session = session; _contentManager = contentManager; _luceneIndexManager = luceneIndexManager; _luceneIndexingService = luceneIndexingService; _authorizationService = authorizationService; _luceneAnalyzerManager = luceneAnalyzerManager; _luceneIndexSettingsService = luceneIndexSettingsService; _queryService = queryService; _liquidTemplateManager = liquidTemplateManager; _contentDefinitionManager = contentDefinitionManager; _notifier = notifier; _siteService = siteService; New = shapeFactory; S = s; H = h; Logger = logger; }
public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter) { if (type != "range") { return(null); } if (!(toFilter is BooleanQuery booleanQuery)) { return(null); } var queryObj = filter as JObject; var range = queryObj.Properties().First(); Query rangeQuery; switch (range.Value.Type) { case JTokenType.Object: var field = range.Name; JToken gt = null; JToken lt = null; var tokenType = JTokenType.None; float? boost = null; bool includeLower = false, includeUpper = false; foreach (var element in ((JObject)range.Value).Properties()) { switch (element.Name.ToLowerInvariant()) { case "gt": gt = element.Value; tokenType = gt.Type; break; case "gte": gt = element.Value; tokenType = gt.Type; includeLower = true; break; case "lt": lt = element.Value; tokenType = lt.Type; break; case "lte": lt = element.Value; tokenType = lt.Type; includeUpper = true; break; case "boost": boost = element.Value.Value <float>(); break; } } if (gt != null && lt != null && gt.Type != lt.Type) { throw new ArgumentException("Lower and upper bound range types don't match"); } switch (tokenType) { case JTokenType.Integer: var minInt = gt?.Value <long>(); var maxInt = lt?.Value <long>(); rangeQuery = NumericRangeQuery.NewInt64Range(field, minInt, maxInt, includeLower, includeUpper); break; case JTokenType.Float: var minFloat = gt?.Value <double>(); var maxFloat = lt?.Value <double>(); rangeQuery = NumericRangeQuery.NewDoubleRange(field, minFloat, maxFloat, includeLower, includeUpper); break; case JTokenType.String: var minString = gt?.Value <string>(); var maxString = lt?.Value <string>(); rangeQuery = TermRangeQuery.NewStringRange(field, minString, maxString, includeLower, includeUpper); break; default: throw new ArgumentException($"Unsupported range value type: {type}"); } if (boost != null) { rangeQuery.Boost = boost.Value; } break; default: throw new ArgumentException("Invalid range query"); } booleanQuery.Add(rangeQuery, Occur.MUST); var queryFilter = new QueryWrapperFilter(rangeQuery); return(new FilteredQuery(booleanQuery, queryFilter)); }
public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query) { if (type != "bool") { return(null); } var boolQuery = new BooleanQuery(); foreach (var property in query.Properties()) { var occur = BooleanClause.Occur.MUST; switch (property.Name.ToLowerInvariant()) { case "must": occur = BooleanClause.Occur.MUST; break; case "mustnot": case "must_not": occur = BooleanClause.Occur.MUST_NOT; break; case "should": occur = BooleanClause.Occur.SHOULD; break; case "boost": boolQuery.Boost = query.Value <float>(); break; case "minimum_should_match": boolQuery.MinimumNumberShouldMatch = query.Value <int>(); break; default: throw new ArgumentException($"Invalid property '{property.Name}' in boolean query"); } switch (property.Value.Type) { case JTokenType.Object: break; case JTokenType.Array: foreach (var item in ((JArray)property.Value)) { if (item.Type != JTokenType.Object) { throw new ArgumentException($"Invalid value in boolean query"); } boolQuery.Add(builder.CreateQueryFragment(context, (JObject)item), occur); } break; default: throw new ArgumentException($"Invalid value in boolean query"); } } return(boolQuery); }
public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter) { if (type != "geo_distance") { return(null); } if (!(toFilter is BooleanQuery booleanQuery)) { return(null); } var queryObj = filter as JObject; if (queryObj.Properties().Count() != 2) { return(null); } var ctx = SpatialContext.Geo; var maxLevels = 11; //results in sub-meter precision for geohash // This can also be constructed from SpatialPrefixTreeFactory SpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels); JProperty distanceProperty = null; JProperty geoProperty = null; foreach (var jProperty in queryObj.Properties()) { if (jProperty.Name.Equals("distance", StringComparison.Ordinal)) { distanceProperty = jProperty; } else { geoProperty = jProperty; } } if (distanceProperty == null || geoProperty == null) { return(null); } var strategy = new RecursivePrefixTreeStrategy(grid, geoProperty.Name); if (!TryParseDistance((string)distanceProperty.Value, out var distanceDegrees)) { return(null); } if (!TryGetPointFromJToken(geoProperty.Value, out var point)) { return(null); } var circle = ctx.MakeCircle(point.X, point.Y, distanceDegrees); var args = new SpatialArgs(SpatialOperation.Intersects, circle); var spatialQuery = strategy.MakeQuery(args); var valueSource = strategy.MakeRecipDistanceValueSource(circle); var valueSourceFilter = new ValueSourceFilter(new QueryWrapperFilter(spatialQuery), valueSource, 0, 1); booleanQuery.Add(new FunctionQuery(valueSource), Occur.MUST); return(new FilteredQuery(booleanQuery, valueSourceFilter)); }
public LuceneSearchService(LuceneIndexManager luceneIndexManager, LuceneAnalyzerManager luceneAnalyzerManager, ILuceneQueryService queryService, ILiquidTemplateManager liquidTemplateManager, ILogger <LuceneSearchService> logger, ISession session, LuceneIndexSettingsService luceneIndexSettingsService) { _luceneIndexManager = luceneIndexManager; _luceneAnalyzerManager = luceneAnalyzerManager; _queryService = queryService; _liquidTemplateManager = liquidTemplateManager; _session = session; _luceneIndexSettingsService = luceneIndexSettingsService; Logger = logger; }
public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter) { if (type != "match") { return(null); } if (!(toFilter is BooleanQuery booleanQuery)) { return(null); } var queryObj = filter as JObject; var first = queryObj.Properties().First(); var boolQuery = new BooleanQuery(); QueryWrapperFilter queryFilter; switch (first.Value.Type) { case JTokenType.String: foreach (var term in LuceneQueryService.Tokenize(first.Name, first.Value.ToString(), context.DefaultAnalyzer)) { boolQuery.Add(new TermQuery(new Term(first.Name, term)), Occur.SHOULD); } break; case JTokenType.Object: var obj = (JObject)first.Value; var value = obj.Property("query")?.Value.Value <string>(); if (obj.TryGetValue("boost", out var boost)) { boolQuery.Boost = boost.Value <float>(); } var occur = Occur.SHOULD; if (obj.TryGetValue("operator", out var op)) { occur = op.ToString() == "and" ? Occur.MUST : Occur.SHOULD; } var terms = LuceneQueryService.Tokenize(first.Name, value, context.DefaultAnalyzer); if (!terms.Any()) { if (obj.TryGetValue("zero_terms_query", out var zeroTermsQuery)) { if (zeroTermsQuery.ToString() == "all") { var matchAllDocsQuery = new MatchAllDocsQuery(); booleanQuery.Add(matchAllDocsQuery, Occur.MUST); queryFilter = new QueryWrapperFilter(matchAllDocsQuery); break; } } } foreach (var term in terms) { boolQuery.Add(new TermQuery(new Term(first.Name, term)), occur); } break; default: throw new ArgumentException("Invalid query"); } booleanQuery.Add(boolQuery, Occur.MUST); queryFilter = new QueryWrapperFilter(boolQuery); return(new FilteredQuery(booleanQuery, queryFilter)); }