public ActionResult <GetProdottiByTestoLiberoQueryResult> Get([FromQuery] CriteriRicerca criteri) { var query = new GetProdottiByTestoLiberoQuery() { Categorie = criteri.Categorie ?? new string[0], Page = criteri.Page, PageSize = criteri.PageSize, Key = criteri.Key }; return(Ok(this.handler.Handle(query))); }
public GetProdottiByTestoLiberoQueryResult Get(GetProdottiByTestoLiberoQuery query) { //creo un array di chiavi dal DTO di input string[] keys = query.Key.Split(" "); Dictionary <string, ProdottoConScore> final = new Dictionary <string, ProdottoConScore>(); List <Prodotto> matchDenominazione = new List <Prodotto>(); List <Prodotto> matchDenominazione1 = new List <Prodotto>(); List <Prodotto> matchImpiegoMacroGruppo = new List <Prodotto>(); List <Prodotto> containsDenominazione = new List <Prodotto>(); List <Prodotto> containsImpiegoMacroGruppo = new List <Prodotto>(); List <ProdottoConScore> prodottoConScoreFinale = new List <ProdottoConScore>(); var collection = dbContext.ProdottiCollection; //collection.Indexes.CreateOne(Builders<Prodotto>.IndexKeys.Text(p => p.MacroGruppo)); //var coll = collection.Find(Builders<Prodotto>.Filter.Text("SEDIE")).ToList(); foreach (string key in keys) { // contiene tutti i prodotti che matchano esattamente in DenominazioneCommerciale con // la chiave matchDenominazione = collection.Find(x => x.DenominazioneCommerciale.ToLower() == key.ToLower()).ToList(); // contiene tutti i prodotti che matchano esattamente in Impiego o Macrogruppo con la chiave matchImpiegoMacroGruppo = collection.Find(x => x.Impiego.ToLower() == key.ToLower() || x.MacroGruppo.ToLower() == key.ToLower()).ToList(); // contiene tutti i prodotti che contengono in DenominazioneCommerciale la chiave containsDenominazione = collection.Find(x => x.DenominazioneCommerciale.ToLower().Contains(key.ToLower())).ToList(); // contiene tutti i prodotti che contengono in Impiego o MacroGruppo la chiave containsImpiegoMacroGruppo = collection.Find(x => x.Impiego.ToLower().Contains(key.ToLower()) || x.MacroGruppo.Contains(key.ToLower())).ToList(); //aggiungo al dizionario tutti i prodotti contenuti in containsDenominazione foreach (Prodotto prod in containsDenominazione) { final.Add(prod.Id, new ProdottoConScore(prod, 1)); } foreach (Prodotto prod in matchDenominazione) { //se il dizionario non contiene l'elemento if (final.ContainsKey(prod.Id) == false) { //lo aggiungo assegnando peso 2, poichè MATCHA esattamente con DenominazioneProdotto final.Add(prod.Id, new ProdottoConScore(prod, 2)); } else { /* * altrimenti se è già presente (quindi si trovava in containsDenominazione) devo aggiornare il suo score, * aggiungendo peso +2 */ final[prod.Id].score += 2; } } foreach (Prodotto prod in containsImpiegoMacroGruppo) { //se il dizionario non contiene l'elemento if (final.ContainsKey(prod.Id) == false) { //lo aggiungo assegnando peso 1, poichè la chiave è CONTENUTA in Impiego o MacroGruppo final.Add(prod.Id, new ProdottoConScore(prod, 1)); } else { /* * altrimenti se è già presente, devo aggiornare il suo score, aggiungendo peso +1 */ final[prod.Id].score += 1; } } foreach (Prodotto prod in matchImpiegoMacroGruppo) { //se il dizionario non contiene l'elemento if (final.ContainsKey(prod.Id) == false) { //lo aggiungo assegnando peso 2, poichè MATCHA esattamente con Impiego o MacroGruppo final.Add(prod.Id, new ProdottoConScore(prod, 2)); } else { /* * altrimenti se è gia presente, devo aggiornare il suo score, aggiungendo peso +2 */ final[prod.Id].score += 2; } } //svuoto le liste matchDenominazione = null; matchImpiegoMacroGruppo = null; containsImpiegoMacroGruppo = null; containsDenominazione = null; } //recupero (solo) i valori dal dizionario foreach (ProdottoConScore prodScore in final.Values) { prodottoConScoreFinale.Add(prodScore); } var prodottiCheMatchanoOrdinati = prodottoConScoreFinale.OrderByDescending(p => p.score); /* * La dimensione massima dell'array di Prodotti in risposta deve essere * minore o uguale a 20. */ if (query.PageSize > 20) { query.PageSize = 20; } var paginaProdotti = prodottiCheMatchanoOrdinati .Skip((query.Page - 1) * query.PageSize) .Take(query.PageSize); var prodottiPerCategoria = prodottiCheMatchanoOrdinati .GroupBy(pp => pp.prodotto.MacroGruppo) .Select(g => new Facet() { Cat = g.Key, Count = g.Count() }) .OrderByDescending(f => f.Count); return(new GetProdottiByTestoLiberoQueryResult() { Criteri = new CriteriRicerca() { Key = query.Key, Categorie = query.Categorie, PageSize = query.PageSize, Page = query.Page }, FacetCategorie = prodottiPerCategoria.ToArray(), Prodotti = paginaProdotti .Select(pp => pp.prodotto) .ToArray(), Risultati = new RisultatiRicerca() { Totale = (int)collection.CountDocuments(new BsonDocument()), Filtrati = prodottiCheMatchanoOrdinati.Count(), FirstIndex = (query.Page - 1) * query.PageSize, LastIndex = ((query.Page - 1) * query.PageSize) + query.PageSize } }); }
/// <summary> /// Ricerca full-text dei prodotti /// </summary> /// <param name="query">DTO di input</param> /// <returns></returns> public GetProdottiByTestoLiberoQueryResult Get(GetProdottiByTestoLiberoQuery query) { var prodotti = this.database.Prodotti; //filtra tutti i prodotti per categorie, se presenti var prodottiFiltratiPerCategoria = prodotti .Where(p => !query.Categorie.Any() || query.Categorie.Contains(p.MacroGruppo)); /* * se prodottiFiltratiPerCategoria è vuoto (dunque non è stata immessa nessuna categoria in input o non * sono state trovate occorrenze) allora prodottiFiltratiPerCategoria conterrà tutti i prodotti del db */ if (prodottiFiltratiPerCategoria.Any() == false) { prodottiFiltratiPerCategoria = prodotti; } /* * viene costruito una classe anonima che conterrà un Prodotto e uno score associato il quale indicherà * la pertinenza del prodotto rispetto alla/e parola/e chiave inserita/e */ var prodottiConPunteggio = prodottiFiltratiPerCategoria.Select(p => new { p = p, score = p.ScoreByMultipleSearchKey(query.Key) }); /* * viene costruito un array prodottiCheMatchanoOrdinati il quale è composto da tutti i prodotti in * prodottiConPunteggio che hanno uno score > 1 (quindi c'è stato un match almeno parziale con la key) * e successivamente l'array viene ordinato per Progressivo */ var prodottiCheMatchanoOrdinati = prodottiConPunteggio .Where(p => p.score > 0) .OrderByDescending(p => p.score) .ThenByDescending(p => p.p.Prog); /* * Viene creata la paginazione */ var paginaProdotti = prodottiCheMatchanoOrdinati .Skip((query.Page - 1) * query.PageSize) .Take(query.PageSize); /* * Costruzione della Facet categoria */ var prodottiPerCategoria = prodottiCheMatchanoOrdinati .GroupBy(pp => pp.p.MacroGruppo) .Select(g => new Facet() { Cat = g.Key, Count = g.Count() }) .OrderByDescending(f => f.Count); /* * Costruzione della Facet anno di firma */ var prodottiPerAnnoFirmaConvenzione = prodottiCheMatchanoOrdinati .GroupBy(pc => pc.p.Firma.Year) .Select(pf => new FacetAnnoFirmaConvenzione() { Anno = pf.Key, Count = pf.Count() }) .OrderByDescending(z => z.Anno); /* * Costruzione della Facet anno di scadenza */ var prodottiPerAnnoScadenzaConvenzione = prodottiCheMatchanoOrdinati .GroupBy(pc => pc.p.Scadenza.Year) .Select(pf => new FacetAnnoScadenzaConvenzione() { Anno = pf.Key, Count = pf.Count() }) .OrderByDescending(z => z.Anno); /* * Costruzione del DTO di output */ return(new GetProdottiByTestoLiberoQueryResult() { Criteri = new CriteriRicerca() { Key = query.Key, Categorie = query.Categorie, PageSize = query.PageSize, Page = query.Page }, FacetCategorie = prodottiPerCategoria.ToArray(), FacetAnnoFirmaConvenzione = prodottiPerAnnoFirmaConvenzione.ToArray(), FacetAnnoScadenzaConvenzione = prodottiPerAnnoScadenzaConvenzione.ToArray(), Prodotti = paginaProdotti .Select(pp => pp.p) .ToArray(), Risultati = new RisultatiRicerca() { Totale = prodotti.Count(), Filtrati = prodottiCheMatchanoOrdinati.Count(), FirstIndex = (query.Page - 1) * query.PageSize, LastIndex = ((query.Page - 1) * query.PageSize) + query.PageSize - 1 } }); }