private BoolQueryDescriptor <FTPEntry> _mustHaveParents(BoolQueryDescriptor <FTPEntry> descriptor, bool HaveParents)
 {
     if (HaveParents)
     {
         return(descriptor.Must(m => m
                                .Exists(e => e
                                        .Field(f => f.Parent)
                                        )
                                ));
     }
     else
     {
         return(descriptor.MustNot(mn => mn
                                   .Exists(e => e
                                           .Field(f => f.Parent)
                                           )
                                   ));
     }
 }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public async Task <ISearchResponse <T> > ToListAsync()
        {
            SearchDescriptor <T>    selector  = new SearchDescriptor <T>();
            BoolQueryDescriptor <T> boolQuery = new BoolQueryDescriptor <T>();

            if (_mustSelector.Count > 0)
            {
                boolQuery.Must(_mustSelector);
            }
            if (_mustNotSelector.Count > 0)
            {
                boolQuery.MustNot(_mustNotSelector);
            }
            if (!string.IsNullOrWhiteSpace(IndexName))
            {
                selector.Index(IndexName);
            }
            selector = selector.Query(q => q.Bool(b => boolQuery)).From(SkipCount ?? 0);
            if (TakeCount > 0)
            {
                selector.Size(TakeCount.Value);
            }
            if (sortor != null)
            {
                selector.Sort(sortor);
            }
            var response = await _searchContext.Context.SearchAsync <T>(selector);

            if (!response.IsValid)
            {
                _searchContext.Logger.LogError($"[Success:{response.ApiCall.Success}]\t{response.ApiCall.Uri}");
                _searchContext.Logger.LogError(response.ApiCall.DebugInformation);
                _searchContext.Logger.LogError(response.ApiCall.OriginalException?.Message);
            }
            return(response);
        }
        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));
            }
        }