Example #1
0
        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);
        }
Example #2
0
        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");
            }
        }
Example #3
0
        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;
        }
Example #4
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));
        }
        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);
        }
Example #6
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));
        }
Example #7
0
 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;
 }
Example #8
0
        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));
        }