public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "simple_query_string")
            {
                return(null);
            }

            var queryString     = query["query"]?.Value <string>();
            var fields          = query["fields"]?.Values <string>() ?? new string[0];
            var defaultOperator = query["default_operator"]?.Value <string>().ToLowerInvariant() ?? "or";
            var weights         = fields.ToDictionary(field => field, field => 1.0f);
            var queryParser     = new SimpleQueryParser(context.DefaultAnalyzer, weights);

            switch (defaultOperator)
            {
            case "and":
                queryParser.DefaultOperator = Occur.MUST;
                break;

            case "or":
                queryParser.DefaultOperator = Occur.SHOULD;
                break;
            }
            return(queryParser.Parse(queryString));
        }
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "term")
            {
                return(null);
            }

            var first = query.Properties().First();

            // A term query has only one member, which can either be a string or an object

            switch (first.Value.Type)
            {
            case JTokenType.String:
                return(new TermQuery(new Term(first.Name, first.Value.ToString())));

            case JTokenType.Object:
                var obj       = (JObject)first.Value;
                var value     = obj.Property("value").Value.Value <string>();
                var termQuery = new TermQuery(new Term(first.Name, value));

                if (obj.TryGetValue("boost", out var boost))
                {
                    termQuery.Boost = boost.Value <float>();
                }

                return(termQuery);

            default: throw new ArgumentException("Invalid term query");
            }
        }
Esempio n. 3
0
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "wildcard")
            {
                return(null);
            }

            var first = query.Properties().First();

            switch (first.Value.Type)
            {
            case JTokenType.String:
                return(new WildcardQuery(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 wildcard query");
                }

                var wildCardQuery = new WildcardQuery(new Term(value.Value <string>()));

                if (obj.TryGetValue("boost", out var boost))
                {
                    wildCardQuery.Boost = boost.Value <float>();
                }

                return(wildCardQuery);

            default: throw new ArgumentException("Invalid wildcard query");
            }
        }
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "match")
            {
                return(null);
            }

            var first = query.Properties().First();

            var boolQuery = new BooleanQuery();

            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);
                }
                return(boolQuery);

            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")
                        {
                            return(new MatchAllDocsQuery());
                        }
                    }
                }

                foreach (var term in terms)
                {
                    boolQuery.Add(new TermQuery(new Term(first.Name, term)), occur);
                }

                return(boolQuery);

            default: throw new ArgumentException("Invalid query");
            }
        }
        public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter)
        {
            if (type != "fuzzy")
            {
                return(null);
            }

            if (!(toFilter is BooleanQuery booleanQuery))
            {
                return(null);
            }

            var queryObj = filter as JObject;
            var first    = queryObj.Properties().First();

            FuzzyQuery fuzzyQuery;

            switch (first.Value.Type)
            {
            case JTokenType.String:
                fuzzyQuery = new FuzzyQuery(new Term(first.Name, first.Value.ToString()));
                break;

            case JTokenType.Object:
                var obj = (JObject)first.Value;

                if (!obj.TryGetValue("value", out var value))
                {
                    throw new ArgumentException("Missing value in fuzzy query");
                }

                obj.TryGetValue("fuzziness", out var fuzziness);
                obj.TryGetValue("prefix_length", out var prefixLength);
                obj.TryGetValue("max_expansions", out var maxExpansions);

                fuzzyQuery = new FuzzyQuery(
                    new Term(first.Name, value.Value <string>()),
                    fuzziness?.Value <int>() ?? LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE,
                    prefixLength?.Value <int>() ?? 0,
                    maxExpansions?.Value <int>() ?? 50,
                    true);

                if (obj.TryGetValue("boost", out var boost))
                {
                    fuzzyQuery.Boost = boost.Value <float>();
                }

                break;

            default: throw new ArgumentException("Invalid fuzzy query");
            }

            booleanQuery.Add(fuzzyQuery, Occur.MUST);
            var queryFilter = new QueryWrapperFilter(fuzzyQuery);

            return(new FilteredQuery(booleanQuery, queryFilter));
        }
Esempio n. 6
0
        public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter)
        {
            if (type != "prefix")
            {
                return(null);
            }

            if (!(toFilter is BooleanQuery booleanQuery))
            {
                return(null);
            }

            var queryObj = filter as JObject;
            var first    = queryObj.Properties().First();

            // A prefix query has only one member, which can either be a string or an object
            PrefixQuery prefixQuery;

            switch (first.Value.Type)
            {
            case JTokenType.String:
                prefixQuery = new PrefixQuery(new Term(first.Name, first.Value.ToString()));
                break;

            case JTokenType.Object:
                var obj = (JObject)first.Value;

                if (obj.TryGetValue("value", out var value))
                {
                    prefixQuery = new PrefixQuery(new Term(first.Name, value.Value <string>()));
                }
                else if (obj.TryGetValue("prefix", out var prefix))
                {
                    prefixQuery = new PrefixQuery(new Term(first.Name, prefix.Value <string>()));
                }
                else
                {
                    throw new ArgumentException("Prefix query misses prefix value");
                }

                if (obj.TryGetValue("boost", out var boost))
                {
                    prefixQuery.Boost = boost.Value <float>();
                }

                break;

            default: throw new ArgumentException("Invalid prefix query");
            }

            booleanQuery.Add(prefixQuery, Occur.MUST);
            var queryFilter = new QueryWrapperFilter(prefixQuery);

            return(new FilteredQuery(booleanQuery, queryFilter));
        }
Esempio n. 7
0
        public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter)
        {
            if (type != "match_phrase")
            {
                return(null);
            }

            if (!(toFilter is BooleanQuery booleanQuery))
            {
                return(null);
            }

            var queryObj = filter as JObject;
            var first    = queryObj.Properties().First();

            var    phraseQuery = new PhraseQuery();
            JToken value;

            switch (first.Value.Type)
            {
            case JTokenType.String:
                value = first.Value;
                break;

            case JTokenType.Object:
                var obj = (JObject)first.Value;

                if (!obj.TryGetValue("value", out value))
                {
                    throw new ArgumentException("Missing value in match phrase query");
                }

                // TODO: read "analyzer" property

                if (obj.TryGetValue("slop", out var slop))
                {
                    phraseQuery.Slop = slop.Value <int>();
                }

                break;

            default: throw new ArgumentException("Invalid wildcard query");
            }

            foreach (var term in LuceneQueryService.Tokenize(first.Name, value.Value <string>(), context.DefaultAnalyzer))
            {
                phraseQuery.Add(new Term(first.Name, term));
            }

            booleanQuery.Add(phraseQuery, Occur.MUST);
            var queryFilter = new QueryWrapperFilter(phraseQuery);

            return(new FilteredQuery(booleanQuery, queryFilter));
        }
        public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter)
        {
            if (type != "geo_bounding_box")
            {
                return(null);
            }

            if (!(toFilter is BooleanQuery booleanQuery))
            {
                return(null);
            }

            var queryObj = filter as JObject;
            var first    = queryObj.Properties().First();

            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);

            var geoPropertyName = first.Name;
            var strategy        = new RecursivePrefixTreeStrategy(grid, geoPropertyName);

            var boundingBox = (JObject)first.Value;

            var topLeftProperty     = boundingBox["top_left"] as JObject;
            var bottomRightProperty = boundingBox["bottom_right"] as JObject;

            if (topLeftProperty == null || bottomRightProperty == null)
            {
                return(null);
            }

            var left   = topLeftProperty["lon"];
            var top    = topLeftProperty["lat"];
            var bottom = bottomRightProperty["lat"];
            var right  = bottomRightProperty["lon"];

            var rectangle = ctx.MakeRectangle((double)left, (double)right, (double)bottom, (double)top);

            var args = new SpatialArgs(SpatialOperation.Intersects, rectangle);

            var spatialQuery      = strategy.MakeQuery(args);
            var valueSource       = strategy.MakeRecipDistanceValueSource(rectangle);
            var valueSourceFilter = new ValueSourceFilter(new QueryWrapperFilter(spatialQuery), valueSource, 0, 1);

            booleanQuery.Add(new FunctionQuery(valueSource), Occur.MUST);

            return(new FilteredQuery(booleanQuery, valueSourceFilter));
        }
Esempio n. 9
0
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "simple_query_string")
            {
                return(null);
            }

            var queryString     = query["query"]?.Value <string>();
            var fields          = query["fields"]?.Value <string>() ?? "";
            var defaultOperator = query["default_operator"]?.Value <string>() ?? "and";
            var queryParser     = new SimpleQueryParser(context.DefaultAnalyzer, "");

            return(queryParser.Parse(queryString));
        }
Esempio n. 10
0
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "query_string")
            {
                return(null);
            }

            var queryString  = query["query"]?.Value <string>();
            var defaultField = query["default_field"]?.Value <string>();

            var queryParser = new QueryParser(context.DefaultVersion, "", context.DefaultAnalyzer);

            return(queryParser.Parse(queryString));
        }
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "match_all")
            {
                return(null);
            }

            var matchAllQuery = new MatchAllDocsQuery();

            if (query.TryGetValue("boost", out var boost))
            {
                matchAllQuery.Boost = boost.Value <float>();
            }

            return(matchAllQuery);
        }
Esempio n. 12
0
        public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter)
        {
            if (type != "terms")
            {
                return(null);
            }

            if (!(toFilter is BooleanQuery booleanQuery))
            {
                return(null);
            }

            var queryObj = filter as JObject;
            var first    = queryObj.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");
            }

            booleanQuery.Add(boolQuery, Occur.MUST);
            var queryFilter = new QueryWrapperFilter(boolQuery);

            return(new FilteredQuery(booleanQuery, queryFilter));
        }
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "prefix")
            {
                return(null);
            }

            var first = query.Properties().First();

            // A prefix query has only one member, which can either be a string or an object

            switch (first.Value.Type)
            {
            case JTokenType.String:
                return(new PrefixQuery(new Term(first.Name, first.Value.ToString())));

            case JTokenType.Object:
                var         obj         = (JObject)first.Value;
                PrefixQuery prefixQuery = null;

                if (obj.TryGetValue("value", out var value))
                {
                    prefixQuery = new PrefixQuery(new Term(first.Name, value.Value <string>()));
                }
                else if (obj.TryGetValue("prefix", out var prefix))
                {
                    prefixQuery = new PrefixQuery(new Term(first.Name, prefix.Value <string>()));
                }
                else
                {
                    throw new ArgumentException("Prefix query misses prefix value");
                }

                if (obj.TryGetValue("boost", out var boost))
                {
                    prefixQuery.Boost = boost.Value <float>();
                }

                return(prefixQuery);

            default: throw new ArgumentException("Invalid prefix query");
            }
        }
        private Query CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, Query query, JToken filter)
        {
            Query filteredQuery = null;
            var   queryObj      = filter as JObject;

            switch (filter.Type)
            {
            case JTokenType.Object:
                var first = queryObj.Properties().First();

                foreach (var queryProvider in _filters)
                {
                    filteredQuery = queryProvider.CreateFilteredQuery(builder, context, first.Name, first.Value, query);

                    if (filteredQuery != null)
                    {
                        break;
                    }
                }
                break;

            case JTokenType.Array:
                foreach (var item in ((JArray)filter))
                {
                    var firstQuery = item.First() as JProperty;

                    foreach (var queryProvider in _filters)
                    {
                        filteredQuery = queryProvider.CreateFilteredQuery(builder, context, firstQuery.Name, firstQuery.Value, query);

                        if (filteredQuery != null)
                        {
                            break;
                        }
                    }
                }
                break;

            default: throw new ArgumentException($"Invalid value in boolean query");
            }

            return(filteredQuery);
        }
Esempio n. 15
0
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "fuzzy")
            {
                return(null);
            }

            var first = query.Properties().First();

            switch (first.Value.Type)
            {
            case JTokenType.String:
                return(new FuzzyQuery(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 fuzzy query");
                }

                obj.TryGetValue("fuzziness", out var fuzziness);
                obj.TryGetValue("prefix_length", out var prefixLength);
                obj.TryGetValue("max_expansions", out var maxExpansions);

                var fuzzyQuery = new FuzzyQuery(
                    new Term(first.Name, value.Value <string>()),
                    fuzziness?.Value <int>() ?? LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE,
                    prefixLength?.Value <int>() ?? 0,
                    maxExpansions?.Value <int>() ?? 50,
                    true);

                if (obj.TryGetValue("boost", out var boost))
                {
                    fuzzyQuery.Boost = boost.Value <float>();
                }

                return(fuzzyQuery);

            default: throw new ArgumentException("Invalid fuzzy query");
            }
        }
Esempio n. 16
0
        public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter)
        {
            if (type != "match_all")
            {
                return(null);
            }

            if (!(toFilter is BooleanQuery booleanQuery))
            {
                return(null);
            }

            var matchAllQuery = new MatchAllDocsQuery();

            booleanQuery.Add(matchAllQuery, Occur.MUST);
            var queryFilter = new QueryWrapperFilter(matchAllQuery);

            return(new FilteredQuery(booleanQuery, queryFilter));
        }
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "simple_query_string")
            {
                return(null);
            }

            var queryString     = query["query"]?.Value <string>();
            var fields          = query["fields"]?.Values <string>() ?? new string[0];
            var defaultOperator = query["default_operator"]?.Value <string>().ToLowerInvariant() ?? "or";
            var weight          = 1.0f;
            var weights         = fields.ToDictionary(field => field, field => weight);

            foreach (var field in fields)
            {
                var fieldWeightArray = field.Split('^', 2);

                if (fieldWeightArray.Length > 1 && Single.TryParse(fieldWeightArray[1], out weight))
                {
                    weights.Remove(field);
                    weights.Add(fieldWeightArray[0], weight);
                }
            }

            var queryParser = new SimpleQueryParser(context.DefaultAnalyzer, weights);

            switch (defaultOperator)
            {
            case "and":
                queryParser.DefaultOperator = Occur.MUST;
                break;

            case "or":
                queryParser.DefaultOperator = Occur.SHOULD;
                break;
            }
            return(queryParser.Parse(queryString));
        }
Esempio n. 18
0
        public Query CreateQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JObject query)
        {
            if (type != "terms")
            {
                return(null);
            }

            var first = query.Properties().First();

            string 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>())), BooleanClause.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);
        }
Esempio n. 19
0
        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);
        }
Esempio n. 20
0
        public async Task <LuceneQueryResults> Query(AdminQueryViewModel model, Boolean returnContentItems)
        {
            //if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes))
            //{
            //    return Unauthorized();
            //}

            // model.Indices = _luceneIndexManager.List().ToArray();
            model.Indices = (await _luceneIndexSettingsService.GetSettingsAsync()).Select(x => x.IndexName).ToArray();

            // Can't query if there are no indices
            //if (model.Indices.Length == 0)
            //{
            //    return RedirectToAction("Index");
            //}

            if (String.IsNullOrEmpty(model.IndexName))
            {
                model.IndexName = model.Indices[0];
            }

            //if (!_luceneIndexManager.Exists(model.IndexName))
            //{
            //    return NotFound();
            //}

            //if (String.IsNullOrWhiteSpace(model.DecodedQuery))
            //{
            //    return View(model);
            //}

            if (String.IsNullOrEmpty(model.Parameters))
            {
                model.Parameters = "{ }";
            }

            //  var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync();

            //  var stopwatch = new Stopwatch();
            //stopwatch.Start();

            var luceneQueryResults = new LuceneQueryResults();

            await _luceneIndexManager.SearchAsync(model.IndexName, async searcher =>
            {
                var analyzer = _luceneAnalyzerManager.CreateAnalyzer("standardanalyzer");
                var context  = new LuceneQueryContext(searcher, LuceneSettings.DefaultVersion, analyzer);

                var templateContext = _liquidTemplateManager.Context;// new TemplateContext();
                var parameters      = JsonConvert.DeserializeObject <Dictionary <string, object> >(model.Parameters);

                foreach (var parameter in parameters)
                {
                    templateContext.SetValue(parameter.Key, parameter.Value);
                }

                var tokenizedContent = await _liquidTemplateManager.RenderAsync(model.DecodedQuery, NullEncoder.Default, templateContext);

                try
                {
                    var parameterizedQuery = JObject.Parse(tokenizedContent);
                    var docs = await _queryService.SearchAsync(context, parameterizedQuery);
                    //  model.Documents = docs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc)).ToList();

                    if (returnContentItems)
                    {
                        // Load corresponding content item versions
                        var contentItemVersionIds = docs.TopDocs.ScoreDocs.Select(x => searcher.Doc(x.Doc).Get("Content.ContentItem.ContentItemVersionId")).ToArray();
                        var contentItems          = await _session.Query <ContentItem, ContentItemIndex>(x => x.ContentItemVersionId.IsIn(contentItemVersionIds)).ListAsync();

                        // Reorder the result to preserve the one from the lucene query
                        var indexed = contentItems.ToDictionary(x => x.ContentItemVersionId, x => x);
                        luceneQueryResults.Items = contentItemVersionIds.Select(x => indexed[x]).ToArray();
                    }
                    else
                    {
                        var results = new List <JObject>();
                        foreach (var document in docs.TopDocs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc)))
                        {
                            results.Add(new JObject(document.Select(x => new JProperty(x.Name, x.GetStringValue()))));
                        }

                        luceneQueryResults.Items = results;
                    }
                }
                catch (Exception e)
                {
                    Logger.LogError(e, "Error while executing query");
                    //  ModelState.AddModelError(nameof(model.DecodedQuery), "Invalid query");
                }

                // stopwatch.Stop();
                // model.Elapsed = stopwatch.Elapsed;
            });

            return(luceneQueryResults);
        }
Esempio n. 21
0
        public async Task <IActionResult> Query(AdminQueryViewModel model, [FromServices] ITokenizer tokenizer)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes))
            {
                return(Unauthorized());
            }

            model.Indices = _luceneIndexManager.List().ToArray();

            // Can't query if there are no indices
            if (model.Indices.Length == 0)
            {
                return(RedirectToAction("Index"));
            }

            if (String.IsNullOrEmpty(model.IndexName))
            {
                model.IndexName = model.Indices[0];
            }

            if (!_luceneIndexManager.Exists(model.IndexName))
            {
                return(NotFound());
            }

            if (String.IsNullOrWhiteSpace(model.DecodedQuery))
            {
                return(View(model));
            }

            if (String.IsNullOrEmpty(model.Parameters))
            {
                model.Parameters = "{ }";
            }

            var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync();

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            await _luceneIndexManager.SearchAsync(model.IndexName, async searcher =>
            {
                var analyzer = _luceneAnalyzerManager.CreateAnalyzer("standardanalyzer");
                var context  = new LuceneQueryContext(searcher, LuceneSettings.DefaultVersion, analyzer);

                var tokenizedContent = tokenizer.Tokenize(model.DecodedQuery, JObject.Parse(model.Parameters));

                try
                {
                    var parameterizedQuery = JObject.Parse(tokenizedContent);
                    var docs        = await _queryService.SearchAsync(context, parameterizedQuery);
                    model.Documents = docs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc)).ToList();
                }
                catch (Exception e)
                {
                    Logger.LogError("Error while executing query: {0}", e.Message);
                    ModelState.AddModelError(nameof(model.DecodedQuery), "Invalid query");
                }

                stopwatch.Stop();
                model.Elapsed = stopwatch.Elapsed;
            });

            return(View(model));
        }
Esempio n. 22
0
        public async Task <IActionResult> Query(AdminQueryViewModel model)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageIndexes))
            {
                return(Forbid());
            }

            model.Indices = (await _luceneIndexSettingsService.GetSettingsAsync()).Select(x => x.IndexName).ToArray();

            // Can't query if there are no indices
            if (model.Indices.Length == 0)
            {
                return(RedirectToAction("Index"));
            }

            if (String.IsNullOrEmpty(model.IndexName))
            {
                model.IndexName = model.Indices[0];
            }

            if (!_luceneIndexManager.Exists(model.IndexName))
            {
                return(NotFound());
            }

            if (String.IsNullOrWhiteSpace(model.DecodedQuery))
            {
                return(View(model));
            }

            if (String.IsNullOrEmpty(model.Parameters))
            {
                model.Parameters = "{ }";
            }

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            await _luceneIndexManager.SearchAsync(model.IndexName, async searcher =>
            {
                var analyzer = _luceneAnalyzerManager.CreateAnalyzer(await _luceneIndexSettingsService.GetIndexAnalyzerAsync(model.IndexName));
                var context  = new LuceneQueryContext(searcher, LuceneSettings.DefaultVersion, analyzer);

                var templateContext = _liquidTemplateManager.Context;
                var parameters      = JsonConvert.DeserializeObject <Dictionary <string, object> >(model.Parameters);

                foreach (var parameter in parameters)
                {
                    templateContext.SetValue(parameter.Key, parameter.Value);
                }

                var tokenizedContent = await _liquidTemplateManager.RenderAsync(model.DecodedQuery, _javaScriptEncoder);

                try
                {
                    var parameterizedQuery = JObject.Parse(tokenizedContent);
                    var luceneTopDocs      = await _queryService.SearchAsync(context, parameterizedQuery);

                    if (luceneTopDocs != null)
                    {
                        model.Documents = luceneTopDocs.TopDocs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc)).ToList();
                        model.Count     = luceneTopDocs.Count;
                    }
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Error while executing query");
                    ModelState.AddModelError(nameof(model.DecodedQuery), S["Invalid query : {0}", e.Message]);
                }

                stopwatch.Stop();
                model.Elapsed = stopwatch.Elapsed;
            });

            return(View(model));
        }
Esempio n. 23
0
        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));
        }
Esempio n. 24
0
        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));
        }