Exemplo n.º 1
0
        /// <summary>
        /// Perform a search with disjunctive facets generating as many queries as number of disjunctive facets
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="disjunctiveFacets">The array of disjunctive facets.</param>
        /// <param name="refinements">The current refinements. Example: { "my_facet1" => ["my_value1", "my_value2"], "my_disjunctive_facet1" => ["my_value1", "my_value2"] }.</param>
        async public Task <JObject> SearchDisjunctiveFacetingAsync(Query query, IEnumerable <string> disjunctiveFacets, Dictionary <string, IEnumerable <string> > refinements = null)
        {
            if (refinements == null)
            {
                refinements = new Dictionary <string, IEnumerable <string> >();
            }
            Dictionary <string, IEnumerable <string> > disjunctiveRefinements = new Dictionary <string, IEnumerable <string> >();

            foreach (string key in refinements.Keys)
            {
                if (disjunctiveFacets.Contains(key))
                {
                    disjunctiveRefinements.Add(key, refinements[key]);
                }
            }

            // build queries
            List <IndexQuery> queries = new List <IndexQuery>();
            // hits + regular facets query
            List <string> filters = new List <string>();

            foreach (string key in refinements.Keys)
            {
                string or    = "(";
                bool   first = true;
                foreach (string value in refinements[key])
                {
                    if (disjunctiveRefinements.ContainsKey(key))
                    {
                        // disjunctive refinements are ORed
                        if (!first)
                        {
                            or += ',';
                        }
                        first = false;
                        or   += String.Format("{0}:{1}", key, value);
                    }
                    else
                    {
                        filters.Add(String.Format("{0}:{1}", key, value));
                    }
                }
                // Add or
                if (disjunctiveRefinements.ContainsKey(key))
                {
                    filters.Add(or + ')');
                }
            }


            queries.Add(new IndexQuery(_indexName, query.clone().SetFacetFilters(filters)));
            // one query per disjunctive facet (use all refinements but the current one + histPerPage=1 + single facet)
            foreach (string disjunctiveFacet in disjunctiveFacets)
            {
                filters = new List <string>();
                foreach (string key in refinements.Keys)
                {
                    if (disjunctiveFacet.Equals(key))
                    {
                        continue;
                    }
                    string or    = "(";
                    bool   first = true;
                    foreach (string value in refinements[key])
                    {
                        if (disjunctiveRefinements.ContainsKey(key))
                        {
                            // disjunctive refinements are ORed
                            if (!first)
                            {
                                or += ',';
                            }
                            first = false;
                            or   += String.Format("{0}:{1}", key, value);
                        }
                        else
                        {
                            filters.Add(String.Format("{0}:{1}", key, value));
                        }
                    }
                    // Add or
                    if (disjunctiveRefinements.ContainsKey(key))
                    {
                        filters.Add(or + ')');
                    }
                }
                queries.Add(new IndexQuery(_indexName, query.clone().SetPage(0).SetNbHitsPerPage(0).EnableAnalytics(false).SetAttributesToRetrieve(new List <string>()).SetAttributesToHighlight(new List <string>()).SetAttributesToSnippet(new List <string>()).SetFacets(new String[] { disjunctiveFacet }).SetFacetFilters(filters)));
            }

            JObject answers = await _client.MultipleQueriesAsync(queries).ConfigureAwait(_client.getContinueOnCapturedContext());

            // aggregate answers
            // first answer stores the hits + regular facets
            JObject aggregatedAnswer      = answers["results"].ToObject <JArray>()[0].ToObject <JObject>();
            JObject disjunctiveFacetsJSON = new JObject();
            bool    first2 = true;

            foreach (JToken answer in answers["results"].ToObject <JArray>())
            {
                if (first2)
                {
                    first2 = false;
                    continue;
                }
                JObject a = answer.ToObject <JObject>();
                foreach (KeyValuePair <string, JToken> elt in a["facets"].ToObject <JObject>())
                {
                    // Add the facet to the disjunctive facet hash
                    disjunctiveFacetsJSON.Add(elt.Key, elt.Value);
                    // concatenate missing refinements
                    if (!disjunctiveRefinements.ContainsKey(elt.Key))
                    {
                        continue;
                    }
                    foreach (string refine in disjunctiveRefinements[elt.Key])
                    {
                        if (disjunctiveFacetsJSON[elt.Key].ToObject <JObject>()[refine] == null)
                        {
                            disjunctiveFacetsJSON[elt.Key].ToObject <JObject>().Add(refine, 0);
                        }
                    }
                }
            }
            aggregatedAnswer.Add("disjunctiveFacets", disjunctiveFacetsJSON.ToObject <JToken>());
            return(aggregatedAnswer);
        }