Přidání fasetové navigace do vyhledávací aplikace

Fasetová navigace se používá k filtrování výsledků dotazů v aplikaci vyhledávací služby, ve které vaše aplikace nabízí ovládací prvky formulářů pro vyhledávání oborů na skupiny dokumentů (například kategorie nebo značky) a Azure AI Search poskytuje datové struktury a filtry, aby se prostředí vrátilo.

V tomto článku se seznámíte se základními kroky pro vytvoření fasetové navigační struktury ve službě Azure AI Search.

  • Nastavení atributů pole v indexu
  • Strukturování požadavku a odpovědi
  • Přidání navigačních ovládacích prvků a filtrů do prezentační vrstvy

Kód v prezentační vrstvě dělá náročné úlohy v fasetovém navigačním prostředí. Ukázky a ukázky uvedené na konci tohoto článku poskytují funkční kód, který vám ukáže, jak všechno spojit dohromady.

Fasetová navigace na vyhledávací stránce

Omezující vlastnosti jsou dynamické a vrací se v dotazu. Odpověď hledání s sebou přináší všechny kategorie omezující vlastnosti použité k navigaci v dokumentech ve výsledku. Nejprve se dotaz spustí a z aktuálních výsledků se načítají omezující vlastnosti a sestaví se do fasetové navigační struktury.

Ve službě Azure AI Search jsou omezující vlastnosti jedné vrstvy hluboko a nemůžou být hierarchické. Pokud neznáte fasetové navigační struktury, zobrazí se na levé straně následující příklad. Počty označují počet shod pro každou omezující vlastnost. Stejný dokument může být reprezentován ve více omezujících vlastnostech.

Screenshot of faceted search results.

Omezující vlastnosti vám můžou pomoct najít, co hledáte, a zároveň zajistit, abyste nezískali žádné výsledky. Jako vývojář vám fasety umožňují zveřejnit nejužitečnější kritéria hledání pro navigaci v indexu vyhledávání.

Povolení omezujících vlastností v indexu

Fasetování je v definici indexu povolené na základě pole po polích, když nastavíte atribut "facetable" na hodnotu true.

I když to není nezbytně nutné, měli byste také nastavit atribut "filtrovatelný", abyste mohli vytvořit potřebné filtry, které vrací fasetové navigační prostředí ve vaší vyhledávací aplikaci.

Následující příklad ukázkového indexu "hotels" zobrazuje "facetable" a "filterable" u polí s nízkou kardinalitou, která obsahují jednotlivé hodnoty nebo krátké fráze: "Category", "Tags", "Rating".

{
  "name": "hotels",  
  "fields": [
    { "name": "hotelId", "type": "Edm.String", "key": true, "searchable": false, "sortable": false, "facetable": false },
    { "name": "Description", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false },
    { "name": "HotelName", "type": "Edm.String", "facetable": false },
    { "name": "Category", "type": "Edm.String", "filterable": true, "facetable": true },
    { "name": "Tags", "type": "Collection(Edm.String)", "filterable": true, "facetable": true },
    { "name": "Rating", "type": "Edm.Int32", "filterable": true, "facetable": true },
    { "name": "Location", "type": "Edm.GeographyPoint" }
  ]
}

Výběr polí

Omezující vlastnosti lze vypočítat přes pole s jednou hodnotou i kolekce. Pole, která fungují nejlépe v fasetové navigaci, mají tyto vlastnosti:

  • Nízká kardinalita (malý počet jedinečných hodnot, které se opakují v dokumentech v korpusu hledání)

  • Krátké popisné hodnoty (jedno nebo dvě slova), které se v navigačním stromu vykreslují pěkně

Hodnoty v poli, nikoli název samotného pole, vytvoří omezující vlastnosti ve fasetové navigační struktuře. Pokud je omezující vlastnost pole řetězce s názvem Barva, omezující vlastnosti budou modré, zelené a všechny ostatní hodnoty daného pole.

Osvědčeným postupem je zkontrolovat hodnoty null, chybně napsané chyby nebo nesrovnalosti v malých a malých a malých písmenech a jedno a množné číslo stejného slova. Ve výchozím nastavení filtry a omezující vlastnosti neprocházejí lexikální analýzou ani kontrolou pravopisu, což znamená, že všechny hodnoty "fasetového" pole jsou potenciální omezující vlastnosti, i když se slova liší o jeden znak. Volitelně můžete k poli "filtrovatelný" a "facetable" přiřadit normalizátor , aby se vyrovnaly varianty v písmenech a znacích.

Výchozí hodnoty v sadách REST a Azure SDK

Pokud používáte některou ze sad Azure SDK, váš kód musí explicitně nastavit atributy pole. Naproti tomu rozhraní REST API má výchozí hodnoty pro atributy pole na základě datového typu. Následující datové typy jsou ve výchozím nastavení "filtrovatelné" a "facetable":

  • Edm.String
  • Edm.DateTimeOffset
  • Edm.Boolean
  • Edm.Int32, Edm.Int64, Edm.Double
  • Kolekce libovolného z výše uvedených typů, například Collection(Edm.String) nebo Collection(Edm.Double)

V fasetové navigaci nemůžete použít Edm.GeographyPoint pole Collection(Edm.GeographyPoint) ani pole. Omezující vlastnosti fungují nejlépe u polí s nízkou kardinalitou. Vzhledem k rozlišení geografických souřadnic je vzácné, že se v dané datové sadě budou všechny dvě sady souřadnic shodovat. Omezující vlastnosti se proto pro geografické souřadnice nepodporují. K omezující vlastnosti podle místa byste potřebovali pole města nebo oblasti.

Tip

Osvědčeným postupem pro optimalizaci výkonu a úložiště je vypnout omezující vlastnosti polí, která by se nikdy neměla používat jako omezující vlastnost. Konkrétně by měla být pole řetězců pro jedinečné hodnoty, jako je ID nebo název produktu, nastavena tak, aby "facetable": false se zabránilo jejich náhodnému (a neefektivnímu) použití v fasetové navigaci. To platí zejména pro rozhraní REST API, které ve výchozím nastavení povoluje filtry a omezující vlastnosti.

Žádost o omezující vlastnost a odpověď

Omezující vlastnosti se zadají v dotazu a fasetová navigační struktura se vrátí v horní části odpovědi. Struktura požadavku a odpovědi je poměrně jednoduchá. Skutečná práce za fasetovou navigaci se ve skutečnosti nachází v prezentační vrstvě, která je popsána v další části.

Následující příklad REST je nekvalifikovaný dotaz ("search": "*"), který je vymezen na celý index (viz ukázka předdefinovaných hotelů). Omezující vlastnosti jsou obvykle seznamem polí, ale tento dotaz zobrazuje jenom jednu pro čitelnější odpověď níže.

POST https://{{service_name}}.search.windows.net/indexes/hotels/docs/search?api-version={{api_version}}
{
    "search": "*",
    "queryType": "simple",
    "select": "",
    "searchFields": "",
    "filter": "",
    "facets": [ "Category"], 
    "orderby": "",
    "count": true
}

Je užitečné inicializovat vyhledávací stránku otevřeným dotazem, aby se plně vyplnila fasetová navigační struktura. Jakmile v požadavku předáte termíny dotazu, bude fasetová navigační struktura vymezena pouze na shody ve výsledcích, nikoli na celý index.

Odpověď pro výše uvedený příklad zahrnuje fasetovou navigační strukturu v horní části. Struktura se skládá z hodnot "Category" a počtu hotelů pro každou z nich. Za ním následuje zbytek výsledků hledání, které sem oříznou kvůli stručnosti. Tento příklad funguje dobře z několika důvodů. Počet omezujících vlastností tohoto pole spadá pod limit (výchozí hodnota je 10), takže se zobrazí všechny a každý hotel v indexu 50 hotelů je reprezentován přesně v jedné z těchto kategorií.

{
    "@odata.context": "https://demo-search-svc.search.windows.net/indexes('hotels')/$metadata#docs(*)",
    "@odata.count": 50,
    "@search.facets": {
        "Category": [
            {
                "count": 13,
                "value": "Budget"
            },
            {
                "count": 12,
                "value": "Resort and Spa"
            },
            {
                "count": 9,
                "value": "Luxury"
            },
            {
                "count": 7,
                "value": "Boutique"
            },
            {
                "count": 5,
                "value": "Suite"
            },
            {
                "count": 4,
                "value": "Extended-Stay"
            }
        ]
    },
    "value": [
        {
            "@search.score": 1.0,
            "HotelId": "1",
            "HotelName": "Secret Point Motel",
            "Description": "The hotel is ideally located on the main commercial artery of the city in the heart of New York. A few minutes away is Time's Square and the historic centre of the city, as well as other places of interest that make New York one of America's most attractive and cosmopolitan cities.",
            "Category": "Boutique",
            "Tags": [
                "pool",
                "air conditioning",
                "concierge"
            ],
            "ParkingIncluded": false,
        }
    ]
}

Syntaxe omezujících vlastností

Parametr dotazu omezující vlastnosti je nastaven na čárkami oddělený seznam polí "facetable" a v závislosti na datovém typu lze dále parametrizovat tak, aby nastavoval počty, pořadí řazení a rozsahy: count:<integer>, sort:<>, interval:<integer>, a values:<list>. Další podrobnosti o parametrech omezující vlastnosti najdete v tématu Parametry dotazu v rozhraní REST API.

POST https://{{service_name}}.search.windows.net/indexes/hotels/docs/search?api-version={{api_version}}
{
    "search": "*",
    "facets": [ "Category", "Tags,count:5", "Rating,values:1|2|3|4|5"],
    "count": true
}

U každého fasetového navigačního stromu je výchozí limit deseti omezujících vlastností. Tato výchozí hodnota dává smysl pro navigační struktury, protože udržuje seznam hodnot na spravovatelnou velikost. Výchozí nastavení můžete přepsat přiřazením hodnoty k počtu. "Tags,count:5" Například zmenšuje počet značek v oddílu Značky na prvních pět.

Pouze pro číselné hodnoty a hodnoty DateTime můžete explicitně nastavit hodnoty v poli omezující vlastnosti (například facet=Rating,values:1|2|3|4|5) a oddělit výsledky do souvislých oblastí (buď rozsahy založené na číselných hodnotách, nebo časových obdobích). Alternativně můžete přidat "interval", jako v facet=Rating,interval:1.

Každá oblast je vytvořená pomocí 0 jako výchozího bodu, hodnoty ze seznamu jako koncového bodu a potom oříznuté z předchozí oblasti, aby se vytvořily diskrétní intervaly.

Nesrovnalosti v počtech omezujících vlastností

Za určitých okolností můžete zjistit, že počty omezujících vlastností nejsou kvůli architektuře horizontálního dělení úplně přesné. Každý index vyhledávání je rozložený do několika horizontálních oddílů a každý horizontální oddíl hlásí počet hlavních N omezujících vlastností podle počtu dokumentů, které se pak zkombinují do jednoho výsledku. Vzhledem k tomu, že se jedná pouze o horní N omezující vlastnosti pro každý horizontální oddíl, je možné vynechat nebo podpočítat odpovídající dokumenty v odpovědi omezující vlastnosti.

Chcete-li zaručit přesnost, můžete uměle nafouknout počet:<číslo> na velké číslo, aby se vynutil úplné generování sestav z každého horizontálního oddílu. Pro neomezené omezující vlastnosti můžete zadat "count": "0" . Nebo můžete nastavit "count" na hodnotu, která je větší nebo rovna počtu jedinečných hodnot fasetového pole. Pokud například fasetujete polem "velikost", které má pět jedinečných hodnot, můžete nastavit "count:5" , aby se zajistilo, že všechny shody budou reprezentovány v odpovědi omezující vlastnosti.

Kompromis s tímto alternativním řešením je vyšší latence dotazů, takže ho používejte jenom v případě potřeby.

Vrstva prezentace

V kódu aplikace je vzor použít parametry fasetového dotazu k vrácení fasetové navigační struktury spolu s výsledky omezující vlastnosti a výraz $filter. Výraz filtru zpracovává událost kliknutí a dále zúží výsledek hledání na základě výběru omezující vlastnosti.

Kombinace omezující vlastnosti a filtru

Následující fragment kódu ze JobsSearch.cs souboru v ukázce NYCJobs přidá vybraný obchodní titul do filtru, pokud vyberete hodnotu z omezující vlastnosti obchodního názvu.

if (businessTitleFacet != "")
  filter = "business_title eq '" + businessTitleFacet + "'";

Tady je další příklad ukázky hotelů. Následující fragment kódu se přidá categoyrFacet do filtru, pokud uživatel vybere hodnotu z omezující vlastnosti kategorie.

if (!String.IsNullOrEmpty(categoryFacet))
    filter = $"category eq '{categoryFacet}'";

HTML pro fasetové navigace

Následující příklad, převzatý ze index.cshtml souboru ukázkové aplikace NYCJobs, ukazuje statickou strukturu HTML pro zobrazení fasetové navigace na stránce výsledků hledání. Seznam omezujících vlastností se sestaví nebo znovu sestaví dynamicky, když odešlete hledaný termín, nebo vyberete nebo vymažete omezující vlastnost.

<div class="widget sidebar-widget jobs-filter-widget">
  <h5 class="widget-title">Filter Results</h5>
    <p id="filterReset"></p>
    <div class="widget-content">

      <h6 id="businessTitleFacetTitle">Business Title</h6>
      <ul class="filter-list" id="business_title_facets">
      </ul>

      <h6>Location</h6>
      <ul class="filter-list" id="posting_type_facets">
      </ul>

      <h6>Posting Type</h6>
      <ul class="filter-list" id="posting_type_facets"></ul>

      <h6>Minimum Salary</h6>
      <ul class="filter-list" id="salary_range_facets">
      </ul>

  </div>
</div>

Dynamické sestavování HTML

Následující fragment kódu z ukázky index.cshtml (také z ukázky NYCJobs) dynamicky sestaví kód HTML tak, aby zobrazil první omezující vlastnost Obchodní titul. Podobné funkce dynamicky vytvářejí html pro ostatní omezující vlastnosti. Každá omezující vlastnost má popisek a počet, který zobrazuje počet nalezených položek pro daný výsledek omezující vlastnosti.

function UpdateBusinessTitleFacets(data) {
  var facetResultsHTML = '';
  for (var i = 0; i < data.length; i++) {
    facetResultsHTML += '<li><a href="javascript:void(0)" onclick="ChooseBusinessTitleFacet(\'' + data[i].Value + '\');">' + data[i].Value + ' (' + data[i].Count + ')</span></a></li>';
  }

  $("#business_title_facets").html(facetResultsHTML);
}

Tipy pro práci s omezujícími vlastnostmi

Tato část je kolekce tipů a alternativních řešení, která můžou být užitečná.

Zachování fasetové navigační struktury asynchronně filtrovaných výsledků

Jednou z výzev omezující navigace ve službě Azure AI Search je, že omezující vlastnosti existují pouze pro aktuální výsledky. V praxi je běžné zachovat statickou sadu omezujících vlastností, aby uživatel mohl přecházet obráceně a odčítat kroky k prozkoumání alternativních cest prostřednictvím obsahu vyhledávání.

I když se jedná o běžný případ použití, není to něco, co fasetová navigační struktura aktuálně poskytuje výchozí nastavení. Vývojáři, kteří chtějí statické omezující vlastnosti, obvykle řeší omezení tím, že vydávají dva filtrované dotazy: jeden vymezený na výsledky, druhý použitý k vytvoření statického seznamu omezujících vlastností pro účely navigace.

Vymazat omezující vlastnosti

Při návrhu stránky výsledků hledání nezapomeňte přidat mechanismus pro vymazání omezujících vlastností. Pokud přidáte zaškrtávací políčka, můžete snadno zjistit, jak filtry vymazat. U jiných rozložení můžete potřebovat vzor s popisem cesty nebo jiný kreativní přístup. V ukázce hotelů v jazyce C# můžete odeslat prázdné hledání, které stránku resetuje. Naproti tomu ukázková aplikace NYCJobs poskytuje kliknutí [X] po vybrané omezující vlastnosti k vymazání omezující vlastnosti, což je silnější vizuální fronta pro uživatele.

Oříznout výsledky omezující vlastnosti s využitím dalších filtrů

Výsledky omezující vlastnosti jsou dokumenty nalezené ve výsledcích hledání, které odpovídají termínu omezující vlastnosti. V následujícím příkladu mají ve výsledcích hledání pro cloud computing 254 položek také interní specifikaci jako typ obsahu. Položky se nemusí nutně vzájemně vylučují. Pokud položka splňuje kritéria obou filtrů, počítá se do každého z nich. Tato duplikace je možná při fasetování polí Collection(Edm.String) , která se často používají k implementaci označování dokumentů.

Search term: "cloud computing"
Content type
   Internal specification (254)
   Video (10)

Obecně platí, že pokud zjistíte, že výsledky omezující vlastnosti jsou konzistentně příliš velké, doporučujeme přidat další filtry, abyste uživatelům poskytli více možností pro zúžení hledání.

Vyhledávání pouze omezující vlastnosti

Pokud vaše aplikace používá fasetovou navigaci výhradně (tj. bez vyhledávacího pole), můžete toto pole označit jako searchable=false, filterable=truefacetable=true a vytvořit tak kompaktnější index. Index nebude obsahovat invertované indexy a nebude existovat žádná analýza textu ani tokenizace. Filtry se provádějí na přesné shodě na úrovni znaků.

Ověření vstupů v době dotazu

Pokud sestavíte seznam omezujících vlastností dynamicky na základě nedůvěryhodného uživatelského vstupu, ověřte, zda jsou názvy omezujících vlastností platné. Názvy při sestavování adres URL můžete také umistit pomocí rozhraní Uri.EscapeDataString() .NET nebo ekvivalentu ve zvolené platformě.

Ukázky a ukázky

Několik ukázek zahrnuje fasetové navigace. Tato část obsahuje odkazy na ukázky a také poznámky, které klientské knihovny a jazyk se používají pro každou z nich.

Přidání vyhledávání do webových aplikací (React)

Kurzy a ukázky v jazyce C#, Python a JavaScript zahrnují fasetovou navigaci a také filtry, návrhy a automatické dokončování. Tyto ukázky používají React pro prezentační vrstvu.

Ukázkový kód a ukázka NYCJobs (Ajax)

Ukázka NYCJobs je aplikace ASP.NET MVC, která používá ajax v prezentační vrstvě. Je k dispozici jako živá ukázková aplikace a zdrojový kód v úložišti Azure-Samples na GitHubu.