/// <summary> /// Vérifie qu'une définition de facette est valide. /// </summary> /// <param name="facetDef">Définition de facette.</param> public void CheckFacet(IFacetDefinition facetDef) { if (!_document.Fields.HasProperty(facetDef.FieldName)) { throw new ElasticException("The Document \"" + _document.DocumentTypeName + "\" is missing a \"" + facetDef.FieldName + "\" property to facet on."); } }
/// <summary> /// Extrait les facets du résultat d'une requête. /// </summary> /// <param name="aggs">Aggrégations Elastic.</param> /// <param name="facetDef">Définition de la facette.</param> /// <returns>Sortie des facettes.</returns> public FacetOutput ExtractFacetOutput(Nest.AggregationsHelper aggs, IFacetDefinition facetDef) { var facetOutput = new FacetOutput(); /* Valeurs renseignées. */ var bucket = aggs.Terms(facetDef.Name); foreach (var b in bucket.Items) { facetOutput.Values.Add(new FacetItem { Code = b.Key, Label = facetDef.ResolveLabel(b.Key), Count = b.DocCount }); } /* Valeurs non renseignées. */ var missingBucket = aggs.Missing(facetDef.Name + MissingFacetPrefix); var missingCount = missingBucket.DocCount; if (missingCount > 0) { facetOutput.Values.Add(new FacetItem { Code = FacetConst.NullValue, Label = "Non renseigné", Count = missingCount }); } return(facetOutput); }
/// <summary> /// Renvoie le handler de facet pour une définition de facet. /// </summary> /// <param name="def">Définition de facet.</param> /// <returns>Handler.</returns> private IFacetHandler <TDocument> GetHandler(IFacetDefinition def) { if (def.GetType() == typeof(PortfolioFacet)) { return(_portfolioHandler); } return(_standardHandler); }
/// <summary> /// Définit l'agrégation correspondant à la facette lors de la recherche à facettes. /// </summary> /// <param name="agg">Descripteur d'agrégation.</param> /// <param name="facet">Définition de la facet.</param> public void DefineAggregation(Nest.AggregationDescriptor <TDocument> agg, IFacetDefinition facet) { /* Récupère le nom du champ. */ string fieldName = _document.Fields[facet.FieldName].FieldName; /* Créé une agrégation sur les valeurs discrètes du champ. */ agg.Terms(facet.Name, st => st.Field(fieldName)); /* Créé une agrégation pour les valeurs non renseignées du champ. */ agg.Missing(facet.Name + MissingFacetPrefix, ad => ad.Field(fieldName)); }
/// <summary> /// Créé la sous-requête QSL de filtrage pour la facette sélectionnée. /// </summary> /// <param name="facet">Sélection de facette.</param> /// <param name="facetDef">Définition de la facette.</param> /// <returns>Sous-requête.</returns> public string CreateFacetSubQuery(string facet, IFacetDefinition facetDef) { var fieldDesc = _document.Fields[facetDef.FieldName]; var fieldName = fieldDesc.FieldName; /* Traite la valeur de sélection NULL */ if (facet == FacetConst.NullValue) { return(_builder.BuildMissingField(fieldName)); } return(_builder.BuildFilter(fieldName, facet)); }
/// <inheritdoc/> public string CreateFacetSubQuery(string facet, IFacetDefinition facetDef, string portfolio) { var fieldDesc = _document.Fields[facetDef.FieldName]; var fieldName = fieldDesc.FieldName; if (string.IsNullOrEmpty(portfolio)) { /* Utilisateur avec un portefeuille vide : on ne filtre pas sur la facette. */ return(string.Empty); } switch (facet) { case InValue: return(_builder.BuildInclusiveInclude(fieldName, portfolio)); case OutValue: return(_builder.BuildExcludeQuery(fieldName, portfolio)); default: return(string.Empty); } }
/// <inheritdoc /> public ICollection <FacetItem> ExtractFacetItemList(Nest.AggregationsHelper aggs, IFacetDefinition facetDef, long total) { var facetOutput = new List <FacetItem>(); /* Valeurs renseignées. */ var agg = aggs.Filters(facetDef.Code); /* Cas où le portefeuille de l'utilisateur est vide : l'agrégation n'est pas définie */ if (agg == null) { /* On considère que tous les documents sont en dehors du portefeuille. */ facetOutput.Add(new FacetItem { Code = OutValue, Label = facetDef.ResolveLabel(OutValue), Count = total }); return(facetOutput); } /* Pour les valeurs inclus / exclus */ foreach (var facetName in new[] { InValue, OutValue }) { /* Ajoute une output s'il y a des documents sur la facet. */ var bucket = agg.NamedBucket(facetName); if (bucket.DocCount > 0) { facetOutput.Add(new FacetItem { Code = facetName, Label = facetDef.ResolveLabel(facetName), Count = bucket.DocCount }); } } return(facetOutput); }
/// <inheritdoc/> public void DefineAggregation(Nest.AggregationContainerDescriptor <TDocument> agg, IFacetDefinition facet, ICollection <IFacetDefinition> facetList, FacetListInput selectedFacets, string portfolio) { if (string.IsNullOrEmpty(portfolio)) { /* Portefeuille de l'utilisateur vide : on ne définit pas d'agregations. */ return; } /* Récupère le nom du champ. */ string fieldName = _document.Fields[facet.FieldName].FieldName; /* On construit la requête de filtrage sur les autres facettes multi-sélectionnables. */ var filterQuery = FacetingUtil.BuildMultiSelectableFacetFilter(_builder, facet, facetList, selectedFacets, CreateFacetSubQuery); /* Créé une agrégation avec deux buckets. */ var inQuery = _builder.BuildAndQuery(_builder.BuildInclusiveInclude(fieldName, portfolio), filterQuery); var outQuery = _builder.BuildAndQuery(_builder.BuildExcludeQuery(fieldName, portfolio), filterQuery); agg.Filters(facet.Code, st => st.NamedFilters(x => x /* Une pour les documents dans le portefeuille */ .Filter(InValue, d => d.QueryString(query => query.Query(inQuery))) /* Une pour les documents absents du portefeuille */ .Filter(OutValue, d => d.QueryString(query => query.Query(outQuery))))); }
/// <summary> /// Crée le filtre pour une facette sur les autres facettes multi-sélectionnables. /// </summary> /// <param name="builder">Query builder.</param> /// <param name="facet">Facette.</param> /// <param name="facetList">Liste des facettes.</param> /// <param name="selectedFacets">Facettes sélectionnées.</param> /// <param name="facetQueryBuilder">Builder de requête pour une facette.</param> /// <returns>La filtre.</returns> public static string BuildMultiSelectableFacetFilter(ElasticQueryBuilder builder, IFacetDefinition facet, ICollection <IFacetDefinition> facetList, FacetListInput selectedFacets, Func <string, IFacetDefinition, string, string> facetQueryBuilder) { return(builder.BuildAndQuery(selectedFacets? .Select(sf => { /* On ne filtre pas sur la facette en cours. */ if (sf.Key == facet.Code) { return null; } var targetFacet = facetList.Single(f => f.Code == sf.Key); /* On n'ajoute que les facettes multi-sélectionnables */ if (targetFacet.IsMultiSelectable == false) { return null; } return builder.BuildOrQuery(sf.Value .Select(v => facetQueryBuilder(v, targetFacet, null)) .ToArray()); }) .Where(sf => sf != null) .ToArray())); }
/// <inheritdoc /> public ICollection <FacetItem> ExtractFacetItemList(Nest.AggregationsHelper aggs, IFacetDefinition facetDef, long total) { var facetOutput = new List <FacetItem>(); /* Valeurs renseignées. */ var bucket = aggs.Filter(facetDef.Code).Terms(facetDef.Code); foreach (var b in bucket.Buckets) { facetOutput.Add(new FacetItem { Code = b.Key, Label = facetDef.ResolveLabel(b.Key), Count = b.DocCount ?? 0 }); } /* Valeurs non renseignées. */ var missingBucket = aggs.Filter(facetDef.Code).Missing(facetDef.Code + MissingFacetPrefix); var missingCount = missingBucket.DocCount; if (missingCount > 0) { facetOutput.Add(new FacetItem { Code = FacetConst.NullValue, Label = "focus.search.results.missing", Count = missingCount }); } return(facetOutput); }
/// <inheritdoc/> public void DefineAggregation(Nest.AggregationContainerDescriptor <TDocument> agg, IFacetDefinition facet, ICollection <IFacetDefinition> facetList, FacetListInput selectedFacets, string portfolio) { /* Récupère le nom du champ. */ var fieldName = _document.Fields[facet.FieldName].FieldName; /* On construit la requête de filtrage sur les autres facettes multi-sélectionnables. */ var filterQuery = FacetingUtil.BuildMultiSelectableFacetFilter(_builder, facet, facetList, selectedFacets, CreateFacetSubQuery); var hasFilterQuery = !string.IsNullOrEmpty(filterQuery); agg.Filter(facet.Code, f => { if (hasFilterQuery) { /* Crée le filtre sur les facettes multi-sélectionnables. */ f.Filter(q => q.QueryString(qs => qs.Query(filterQuery))); } return(f.Aggregations(aa => aa /* Créé une agrégation sur les valeurs discrètes du champ. */ .Terms(facet.Code, st => st.Field(fieldName).Size(50)) /* Créé une agrégation pour les valeurs non renseignées du champ. */ .Missing(facet.Code + MissingFacetPrefix, ad => ad.Field(fieldName)))); }); }