public Task <TopDocs> SearchAsync(LuceneQueryContext context, JObject queryObj)
        {
            var queryProp = queryObj["query"] as JObject;

            if (queryProp == null)
            {
                throw new ArgumentException("Query DSL requires a [query] property");
            }

            var query = CreateQueryFragment(context, queryProp);

            var sortProperty = queryObj["sort"];
            var fromProperty = queryObj["from"];
            var sizeProperty = queryObj["size"];

            var size = sizeProperty?.Value <int>() ?? 50;
            var from = fromProperty?.Value <int>() ?? 0;

            string sortField  = null;
            string sortOrder  = null;
            var    sortFields = new List <SortField>();

            if (sortProperty != null)
            {
                if (sortProperty.Type == JTokenType.String)
                {
                    sortField = sortProperty.ToString();
                    sortFields.Add(new SortField(sortField, SortFieldType.STRING, sortOrder == "desc"));
                }
                else if (sortProperty.Type == JTokenType.Object)
                {
                    sortField = ((JProperty)sortProperty.First).Name;
                    sortOrder = ((JProperty)sortProperty.First).Value["order"].ToString();
                    sortFields.Add(new SortField(sortField, SortFieldType.STRING, sortOrder == "desc"));
                }
                else if (sortProperty.Type == JTokenType.Array)
                {
                    foreach (var item in sortProperty.Children())
                    {
                        sortField = ((JProperty)item.First).Name;
                        sortOrder = ((JProperty)item.First).Value["order"].ToString();
                        sortFields.Add(new SortField(sortField, SortFieldType.STRING, sortOrder == "desc"));
                    }
                }
            }

            TopDocs docs = context.IndexSearcher.Search(
                query,
                size + from,
                sortField == null ? Sort.RELEVANCE : new Sort(sortFields.ToArray())
                );

            if (from > 0)
            {
                docs = new TopDocs(docs.TotalHits - from, docs.ScoreDocs.Skip(from).ToArray(), docs.MaxScore);
            }

            return(Task.FromResult(docs));
        }
Exemplo n.º 2
0
        public async Task <IQueryResults> ExecuteQueryAsync(Query query, IDictionary <string, object> parameters)
        {
            var luceneQuery        = query as LuceneQuery;
            var luceneQueryResults = new LuceneQueryResults();

            await _luceneIndexProvider.SearchAsync(luceneQuery.Index, async searcher =>
            {
                var templateContext = _liquidTemplateManager.Context;
                // await  templateContext.ContextualizeAsync(_serviceProvider);

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

                var tokenizedContent   = await _liquidTemplateManager.RenderAsync(luceneQuery.Template, _javaScriptEncoder);
                var parameterizedQuery = JObject.Parse(tokenizedContent);

                var analyzer             = _luceneAnalyzerManager.CreateAnalyzer(await _luceneIndexSettingsService.GetIndexAnalyzerAsync(luceneQuery.Index));
                var context              = new LuceneQueryContext(searcher, LuceneSettings.DefaultVersion, analyzer);
                var docs                 = await _queryService.SearchAsync(context, parameterizedQuery);
                luceneQueryResults.Count = docs.Count;

                if (luceneQuery.ReturnContentItems)
                {
                    // We always return an empty collection if the bottom lines queries have no results.
                    luceneQueryResults.Items = new List <ContentItem>();

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

                    // Reorder the result to preserve the one from the lucene query
                    if (dbContentItems.Any())
                    {
                        var dbContentItemVersionIds = dbContentItems.ToDictionary(x => x.ContentItemVersionId, x => x);
                        var indexedAndInDB          = indexedContentItemVersionIds.Where(dbContentItemVersionIds.ContainsKey);
                        luceneQueryResults.Items    = indexedAndInDB.Select(x => dbContentItemVersionIds[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;
                }
            });

            return(luceneQueryResults);
        }
        public async Task <object> ExecuteQueryAsync(Query query, IDictionary <string, object> parameters)
        {
            var    luceneQuery = query as LuceneQuery;
            object result      = null;

            await _luceneIndexProvider.SearchAsync(luceneQuery.Index, async searcher =>
            {
                var templateContext = new TemplateContext();

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

                var tokenizedContent   = await _liquidTemplateManager.RenderAsync(luceneQuery.Template, templateContext);
                var parameterizedQuery = JObject.Parse(tokenizedContent);

                var analyzer = _luceneAnalyzerManager.CreateAnalyzer(LuceneSettings.StandardAnalyzer);
                var context  = new LuceneQueryContext(searcher, LuceneSettings.DefaultVersion, analyzer);
                var docs     = await _queryService.SearchAsync(context, parameterizedQuery);

                if (luceneQuery.ReturnContentItems)
                {
                    // Load corresponding content item versions
                    var contentItemVersionIds = docs.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);
                    result      = contentItemVersionIds.Select(x => indexed[x]).ToArray();
                }
                else
                {
                    var results = new List <JObject>();
                    foreach (var document in docs.ScoreDocs.Select(hit => searcher.Doc(hit.Doc)))
                    {
                        results.Add(new JObject(document.Select(x => new JProperty(x.Name, x.GetStringValue()))));
                    }

                    result = results;
                }
            });

            return(result);
        }
Exemplo n.º 4
0
        public Query CreateQueryFragment(LuceneQueryContext context, JObject queryObj)
        {
            var first = queryObj.Properties().First();

            Query query = null;

            foreach (var queryProvider in _queryProviders)
            {
                query = queryProvider.CreateQuery(this, context, first.Name, (JObject)first.Value);

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

            return(query);
        }