Example #1
0
        private static Func <QueryContainerDescriptor <TIndexItem>, QueryContainer> CreateQuery(ISearchArgs searchArgs,
                                                                                                Collection <TextSearchField <TIndexItem> > textSearchFields,
                                                                                                ICollection <Func <QueryContainerDescriptor <TIndexItem>, QueryContainer> > filters =
                                                                                                null)
        {
            var boolQueryDescriptor = new BoolQueryDescriptor <TIndexItem>();

            if (!string.IsNullOrWhiteSpace(searchArgs.SearchText))
            {
                if (textSearchFields == null || !textSearchFields.Any())
                {
                    throw new ElasticSearchException("At least one text field need to be specified for text search");
                }

                var textSearch = WildcardTextSearch(searchArgs.SearchText, textSearchFields);
                boolQueryDescriptor.Must(textSearch);
            }

            filters ??= new Collection <Func <QueryContainerDescriptor <TIndexItem>, QueryContainer> >();

            boolQueryDescriptor.Filter(filters);

            QueryContainer Query(QueryContainerDescriptor <TIndexItem> q) => q.Bool(b => boolQueryDescriptor);

            return(Query);
        }
        public static BoolQueryDescriptor <T> Filter <T>(
            this BoolQueryDescriptor <T> value,
            object filter,
            IDictionary <Type, Func <object, string> > filterValueFormatters = null)
            where T : class
        {
            if (filter == null)
            {
                return(value);
            }

            var mustQueries = FilterLogic.GenerateMustQueriesFromFilter <T>(filter, filterValueFormatters);

            if (mustQueries.Any())
            {
                return(value.Filter(mustQueries));
            }

            return(value);
        }
        public override async Task <IEnumerable <ArtifactSearchResult> > GetSemanticSearchSuggestions(SearchEngineParameters searchEngineParameters)
        {
            try
            {
                var index = await SemanticSearchRepository.GetSemanticSearchIndex();

                if (String.IsNullOrEmpty(index))
                {
                    // Returning empty results when index has not been created yet.
                    return(new List <ArtifactSearchResult>());
                }
                PerformIndexHealthCheck(index);

                // Setting default index name on the connection, otherwise the search request will fail
                _elasticClient.ConnectionSettings.DefaultIndices.Clear();
                _elasticClient.ConnectionSettings.DefaultIndices.Add(typeof(SemanticSearchItem), index);

                var searchText = await SemanticSearchRepository.GetSemanticSearchText(searchEngineParameters.ArtifactId,
                                                                                      searchEngineParameters.UserId);

                // Create the bool query descripter that just searchs for the searchText we constructed
                var boolQueryDescriptor = new BoolQueryDescriptor <SemanticSearchItem>();
                boolQueryDescriptor.Must(GetMoreLikeThisQuery(searchText));

                // Dont return back result for the current artifact id we're searching against
                boolQueryDescriptor.MustNot(GetArtifactIdMatchQuery(searchEngineParameters.ArtifactId));

                // If not instance admin, use the list of accessible project ids to filter out, otherwise no need to filter
                if (!searchEngineParameters.IsInstanceAdmin)
                {
                    boolQueryDescriptor.Filter(GetContainsProjectIdsQuery(searchEngineParameters.AccessibleProjectIds));
                }

                // Creates the search descriptor
                var searchDescriptor = new SearchDescriptor <SemanticSearchItem>();
                searchDescriptor.Index(index).Size(searchEngineParameters.PageSize).Query(q => q.Bool(b => boolQueryDescriptor));
                var results = await _elasticClient.SearchAsync <SemanticSearchItem>(searchDescriptor);

                var hits    = results.Hits;
                var itemIds = new List <int>();
                hits.ForEach(a =>
                {
                    int output;
                    if (Int32.TryParse(a.Id, out output))
                    {
                        itemIds.Add(output);
                    }
                });

                // parse the artifact ids into a artifactsearchresult to return to the caller
                return(await GetArtifactSearchResultsFromItemIds(itemIds.Distinct().ToList(), searchEngineParameters.UserId));
            }
            catch (Exception ex)
            {
                if (ex is ElasticsearchConfigurationException)
                {
                    throw;
                }
                throw new ElasticsearchException(I18NHelper.FormatInvariant("Elastic search failed to process search. Exception:{0}", ex));
            }
        }