Ejemplo n.º 1
0
        internal IQueryResponse <Dictionary <string, object> > Execute(ElasticSearchQuery query, Type resultType)
        {
            var index = _context.Index as ElasticSearchIndex;

            if (index == null)
            {
                return(new QueryResponse <Dictionary <string, object> >());
            }

            var descriptor = new SearchDescriptor <Dictionary <string, object> >();

            descriptor.Query(query.Query);

            //TODO: need to determine how to allow type specification, so that we don't have to hard-code AllTypes
            //NEST generates the search query URL based on the descriptor type, so if we use Dictionary<string, object> as the descriptor type, the query URL is:
            //http://[server]:9200/[indexname]/dictionary`2s/_search
            //instead we want it to be:
            //http://[server]:9200/[indexname]/_search
            //when searching over all types. so basically, we want the default to AllTypes unless a specific type is used.
            //In the context of Sitecore search, is it even possible to specify a type for the search? probably, but would need some sort of type mapping...
            descriptor.AllTypes();

            if (query.Filter != null)
            {
                descriptor.Filter(filterDescriptor => filterDescriptor.Query(q => query.Filter));
            }

            if (!Settings.DefaultLanguage.StartsWith(_cultureCode))
            {
                descriptor.Filter(f => f.Query(q => q.Term("_language", _cultureCode)));
            }

            var isResultsSizeSet = false;

            if (query.Methods != null)
            {
                var fields = new List <string>();

                var selectMethods = (from m in query.Methods
                                     where m.MethodType == QueryMethodType.Select
                                     select(SelectMethod) m).ToList <SelectMethod>();

                if (selectMethods.Any())
                {
                    foreach (var method in selectMethods)
                    {
                        fields.AddRange(method.FieldNames.Select(fieldName => fieldName.ToLowerInvariant()));
                    }

                    if (!_context.SecurityOptions.HasFlag(SearchSecurityOptions.DisableSecurityCheck))
                    {
                        fields.Add("_uniqueid");
                        fields.Add("_datasource");
                    }
                }

                var getResultsMethods = (from m in query.Methods
                                         where m.MethodType == QueryMethodType.GetResults
                                         select(GetResultsMethod) m).ToList <GetResultsMethod>();

                if (getResultsMethods.Any())
                {
                    if (fields.Count > 0)
                    {
                        fields.Add("score");
                    }
                }

                if (fields.Count > 0)
                {
                    descriptor.Fields(fields.ToArray());
                }

                var orderByMethods = (from m in query.Methods
                                      where m.MethodType == QueryMethodType.OrderBy
                                      select(OrderByMethod) m).ToList <OrderByMethod>();

                if (orderByMethods.Any())
                {
                    foreach (var method in orderByMethods)
                    {
                        var fieldName = method.Field;
                        switch (method.SortDirection)
                        {
                        case SortDirection.Ascending:
                            descriptor.SortAscending(fieldName);
                            break;

                        case SortDirection.Descending:
                            descriptor.SortDescending(fieldName);
                            break;
                        }
                    }
                }

                var skipMethods = (from m in query.Methods
                                   where m.MethodType == QueryMethodType.Skip
                                   select(SkipMethod) m).ToList <SkipMethod>();

                if (skipMethods.Any())
                {
                    var num = skipMethods.Sum(skipMethod => skipMethod.Count);
                    descriptor.Skip(num);
                }

                var takeMethods = (from m in query.Methods
                                   where m.MethodType == QueryMethodType.Take
                                   select(TakeMethod) m).ToList <TakeMethod>();

                if (takeMethods.Any())
                {
                    var num2 = takeMethods.Sum(takeMethod => takeMethod.Count);
                    descriptor.Size(num2);                     //Take is actually just an alias for Size in NEST, so just use Size instead.
                    isResultsSizeSet = true;
                }

                var countMethods = (from m in query.Methods
                                    where m.MethodType == QueryMethodType.Count
                                    select(CountMethod) m).ToList <CountMethod>();

                if (query.Methods.Count == 1 && countMethods.Any())
                {
                    descriptor.Size(0);                     //TODO: is using Size appropriate here? and is "0" the proper value to send?
                    isResultsSizeSet = true;
                }

                var anyMethods = (from m in query.Methods
                                  where m.MethodType == QueryMethodType.Any
                                  select(AnyMethod) m).ToList <AnyMethod>();

                if (query.Methods.Count == 1 && anyMethods.Any())
                {
                    descriptor.Size(0);                     //TODO: is using Size appropriate here? and is "0" the proper value to send?
                    isResultsSizeSet = true;
                }

                var getFacetsMethods = (from m in query.Methods
                                        where m.MethodType == QueryMethodType.GetFacets
                                        select(GetFacetsMethod) m).ToList <GetFacetsMethod>();

                //TODO: implement facet querying
                if ((query.FacetQueries.Count > 0) && (getFacetsMethods.Any() || getResultsMethods.Any()))
                {
                    //foreach (var facetQuery in GetFacetsPipeline.Run(new GetFacetsArgs(null, query.FacetQueries, _context.Index.Configuration.VirtualFieldProcessors, _context.Index.FieldNameTranslator)).FacetQueries.ToHashSet())
                    //{
                    //	if (!facetQuery.FieldNames.Any())
                    //		continue;

                    //	var nullable = facetQuery.MinimumResultCount;
                    //	if (facetQuery.FieldNames.Count() == 1)
                    //	{
                    //		var fieldNameTranslator = FieldNameTranslator as ElasticSearchFieldNameTranslator;
                    //		var indexFieldName = facetQuery.FieldNames.First();
                    //		if (((fieldNameTranslator != null) && (indexFieldName == fieldNameTranslator.StripKnownExtensions(indexFieldName))) && (_context.Index.Configuration.FieldMap.GetFieldConfiguration(indexFieldName) == null))
                    //		{
                    //			indexFieldName = fieldNameTranslator.GetIndexFieldName(indexFieldName.Replace("__", "!").Replace("_", " ").Replace("!", "__"), true);
                    //		}
                    //		IElasticSearchFacetQuery[] queries = new IElasticSearchFacetQuery[1];
                    //		ElasticSearchFacetFieldQuery query2 = new ElasticSearchFacetFieldQuery(indexFieldName)
                    //			{
                    //				MinCount = nullable
                    //			};
                    //		queries[0] = query2;
                    //		options.AddFacets(queries);
                    //	}
                    //	if (facetQuery.FieldNames.Any())
                    //	{
                    //		IElasticSearchFacetQuery[] queryArray2 = new IElasticSearchFacetQuery[1];
                    //		ElasticSearchFacetPivotQuery query3 = new ElasticSearchFacetPivotQuery
                    //			{
                    //				Fields = new[] { string.Join(",", facetQuery.FieldNames) },
                    //				MinCount = nullable
                    //			};
                    //		queryArray2[0] = query3;
                    //		options.AddFacets(queryArray2);
                    //	}
                    //}
                }
            }

            if (!isResultsSizeSet)
            {
                descriptor.Size(ContentSearchConfigurationSettings.SearchMaxResults);
            }

            //var blee = JsonConvert.SerializeObject(descriptor, Formatting.Indented);

            var serializedDescriptor = index.Client.Serialize(descriptor);

            SearchLog.Log.Info("Serialized Query - " + serializedDescriptor);

            var response = index.Client.Search(descriptor);

            if (!response.ConnectionStatus.Success)
            {
                SearchLog.Log.Error("Query exception - " + response.ConnectionStatus.Error.OriginalException);
            }

            return(response);
        }