Jak pracować z wynikami wyszukiwania w usłudze Azure AI Search

W tym artykule wyjaśniono, jak pracować z odpowiedzią na zapytanie w usłudze Azure AI Search. Struktura odpowiedzi jest określana przez parametry w samym zapytaniu, zgodnie z opisem w artykule Search Documents (REST) lub SearchResults Class (Azure for .NET).

Parametry zapytania określają:

  • Wybór pola
  • Liczba dopasowań znalezionych w indeksie zapytania
  • Stronicowanie wyników
  • Liczba wyników w odpowiedzi (domyślnie do 50)
  • Kolejność sortowania
  • Wyróżnianie terminów w wyniku, dopasowywanie całego lub częściowego terminu w treści

Kompozycja wyników

Wyniki są tabelaryczne, składające się z pól wszystkich pól "pobieralnych" lub ograniczonych tylko do tych pól określonych w parametrach $select . Wiersze to pasujące dokumenty.

Możesz wybrać pola w wynikach wyszukiwania. Chociaż dokument wyszukiwania może zawierać dużą liczbę pól, zazwyczaj tylko kilka z nich jest potrzebnych do reprezentowania każdego dokumentu w wynikach. W żądaniu zapytania dołącz polecenie $select=<field list> , aby określić, które pola "można pobrać" powinny być wyświetlane w odpowiedzi.

Wybierz pola, które oferują kontrast i różnice między dokumentami, zapewniając wystarczające informacje, aby zaprosić odpowiedź klikniętą na część użytkownika. W witrynie handlu elektronicznego może to być nazwa produktu, opis, marka, kolor, rozmiar, cena i ocena. W przypadku wbudowanego indeksu hotels-sample może to być pola "select" w poniższym przykładzie:

POST /indexes/hotels-sample-index/docs/search?api-version=2020-06-30 
    {  
      "search": "sandy beaches",
      "select": "HotelId, HotelName, Description, Rating, Address/City"
      "count": true
    }

Uwaga

W przypadku obrazów w wynikach, takich jak zdjęcie produktu lub logo, zapisz je poza usługą Azure AI Search, ale dodaj pole w indeksie, aby odwoływać się do adresu URL obrazu w dokumencie wyszukiwania. Przykładowe indeksy demonstrujące obrazy w wynikach obejmują pokaz realestate-sample-us (wbudowany przykładowy zestaw danych, który można łatwo skompilować w kreatorze importu danych) oraz demonstracyjną aplikację New York City Jobs.

Wskazówki w przypadku nieoczekiwanych wyników

Czasami substancja, a nie struktura wyników są nieoczekiwane. Na przykład może się okazać, że niektóre wyniki wydają się być duplikatami lub wynik, który powinien pojawić się w górnej części, znajduje się w dolnej części wyników. Gdy wyniki zapytania są nieoczekiwane, możesz wypróbować te modyfikacje zapytań, aby sprawdzić, czy wyniki się poprawią:

  • Zmień searchMode=any wartość (domyślną), aby searchMode=all wymagać dopasowania we wszystkich kryteriach zamiast kryteriów. Jest to szczególnie istotne, gdy operatory logiczne są uwzględniane w zapytaniu.

  • Poeksperymentuj z różnymi analizatorami leksykalnymi lub analizatorami niestandardowymi, aby sprawdzić, czy zmienia wynik zapytania. Analizator domyślny podzieli wyrazy na łączniki i zmniejszy wyrazy do formularzy głównych, co zwykle poprawia niezawodność odpowiedzi zapytania. Jeśli jednak musisz zachować łączniki lub jeśli ciągi zawierają znaki specjalne, może być konieczne skonfigurowanie analizatorów niestandardowych w celu upewnienia się, że indeks zawiera tokeny w odpowiednim formacie. Aby uzyskać więcej informacji, zobacz Wyszukiwanie częściowe terminy i wzorce ze znakami specjalnymi (łączniki, symbol wieloznaczny, regex, wzorce).

Zliczanie dopasowań

Parametr count zwraca liczbę dokumentów w indeksie, które są uznawane za dopasowanie zapytania. Aby zwrócić liczbę, dodaj $count=true do żądania zapytania. Nie ma maksymalnej wartości nałożonej przez usługę wyszukiwania. W zależności od zapytania i zawartości dokumentów liczba może być tak wysoka, jak każdy dokument w indeksie.

Liczba jest dokładna, gdy indeks jest stabilny. Jeśli system aktywnie dodawa, aktualizuje lub usuwa dokumenty, liczba będzie przybliżona, z wyłączeniem wszystkich dokumentów, które nie są w pełni indeksowane.

Liczba nie będzie miała wpływu na rutynową konserwację ani inne obciążenia w usłudze wyszukiwania. Jeśli jednak masz wiele partycji i jedną replikę, możesz doświadczyć krótkoterminowych wahań liczby dokumentów (kilka minut) podczas ponownego uruchamiania partycji.

Napiwek

Aby sprawdzić operacje indeksowania, możesz potwierdzić, czy indeks zawiera oczekiwaną liczbę dokumentów, dodając puste $count=true zapytanie wyszukiwania search=* . Wynikiem jest pełna liczba dokumentów w indeksie.

Podczas testowania składni zapytania można szybko określić, $count=true czy modyfikacje zwracają większe lub mniejsze wyniki, co może być przydatne.

Stronicowanie wyników

Domyślnie aparat wyszukiwania zwraca maksymalnie 50 pierwszych dopasowań. 50 pierwszych jest określanych przez wynik wyszukiwania, przy założeniu, że zapytanie jest wyszukiwaniem pełnotekstowym lub semantycznym. W przeciwnym razie 50 pierwszych to dowolna kolejność dla dokładnie dopasowanych zapytań (gdzie jednolite "@searchScore=1.0" wskazuje dowolną klasyfikację.

Aby kontrolować stronicowanie wszystkich dokumentów zwracanych w zestawie wyników, dodaj $top parametry i $skip do żądania zapytania GET lub topskip do żądania zapytania POST. Poniższa lista zawiera opis logiki.

  • Zwróć pierwszy zestaw 15 pasujących dokumentów oraz liczbę wszystkich dopasowań: GET /indexes/<INDEX-NAME>/docs?search=<QUERY STRING>&$top=15&$skip=0&$count=true

  • Zwróć drugi zestaw, pomijając pierwsze 15, aby uzyskać następną 15: $top=15&$skip=15. Powtórz dla trzeciego zestawu 15: $top=15&$skip=30

Wyniki zapytań podzielonych na strony nie są gwarantowane stabilnie, jeśli indeks bazowy się zmienia. Stronicowanie zmienia wartość $skip dla każdej strony, ale każde zapytanie jest niezależne i działa w bieżącym widoku danych, ponieważ istnieje w indeksie w czasie zapytania (innymi słowy, nie ma buforowania ani migawki wyników, takich jak te znajdujące się w bazie danych ogólnego przeznaczenia).

Poniżej przedstawiono przykład sposobu pobierania duplikatów. Załóżmy indeks z czterema dokumentami:

{ "id": "1", "rating": 5 }
{ "id": "2", "rating": 3 }
{ "id": "3", "rating": 2 }
{ "id": "4", "rating": 1 }

Teraz załóżmy, że wyniki są zwracane dwa naraz, uporządkowane według klasyfikacji. Wykonasz to zapytanie, aby uzyskać pierwszą stronę wyników: $top=2&$skip=0&$orderby=rating desc, generując następujące wyniki:

{ "id": "1", "rating": 5 }
{ "id": "2", "rating": 3 }

W usłudze załóżmy, że piąty dokument jest dodawany do indeksu między wywołaniami zapytania: { "id": "5", "rating": 4 }. Wkrótce potem wykonasz zapytanie, aby pobrać drugą stronę: $top=2&$skip=2&$orderby=rating desci uzyskać następujące wyniki:

{ "id": "2", "rating": 3 }
{ "id": "3", "rating": 2 }

Zwróć uwagę, że dokument 2 jest pobierany dwa razy. Jest to spowodowane tym, że nowy dokument 5 ma większą wartość klasyfikacji, więc sortuje przed dokumentem 2 i ląduje na pierwszej stronie. Chociaż to zachowanie może być nieoczekiwane, typowe jest zachowanie wyszukiwarki.

Stronicowanie dużej liczby wyników

Korzystanie z $top zapytania wyszukiwania i $skip umożliwia stronicowanie do 100 000 wyników, ale co zrobić, jeśli wyniki są większe niż 100 000? Aby stronicować tę dużą odpowiedź, użyj kolejności sortowania i filtru zakresu jako obejścia problemu .$skip

W tym obejście sortowanie i filtrowanie są stosowane do pola identyfikatora dokumentu lub innego pola, które jest unikatowe dla każdego dokumentu. Unikatowe pole musi zawierać filterable atrybuty i sortable atrybuty w indeksie wyszukiwania.

  1. Wyślij zapytanie, aby zwrócić pełną stronę posortowanych wyników.

    POST /indexes/good-books/docs/search?api-version=2020-06-30
        {  
          "search": "divine secrets",
          "top": 50,
          "orderby": "id asc"
        }
    
  2. Wybierz ostatni wynik zwrócony przez zapytanie wyszukiwania. Przykładowy wynik z tylko wartością "id" jest pokazany tutaj.

    {
        "id": "50"
    }
    
  3. Użyj tej wartości "id" w zapytaniu zakresu, aby pobrać następną stronę wyników. To pole "id" powinno mieć unikatowe wartości. W przeciwnym razie stronicowanie może zawierać zduplikowane wyniki.

    POST /indexes/good-books/docs/search?api-version=2020-06-30
        {  
          "search": "divine secrets",
          "top": 50,
          "orderby": "id asc",
          "filter": "id ge 50"
        }
    
  4. Stronicowanie kończy się, gdy zapytanie zwraca zero wyników.

Uwaga

Atrybuty "filtrowalne" i "sortowalne" można włączyć tylko wtedy, gdy pole jest najpierw dodawane do indeksu, nie można ich włączyć w istniejącym polu.

Porządkowanie wyników

W kwerendzie wyszukiwania pełnotekstowego wyniki można sklasyfikować według:

  • wynik wyszukiwania
  • semantyczny wynik reranker
  • kolejność sortowania w polu "sortowalnym"

Możesz również zwiększyć wszystkie dopasowania znalezione w określonych polach, dodając profil oceniania.

Kolejność według wyniku wyszukiwania

W przypadku zapytań wyszukiwania pełnotekstowego wyniki są automatycznie klasyfikowane według wyniku wyszukiwania, obliczane na podstawie częstotliwości terminów i zbliżenia w dokumencie (pochodzącym z serwera TF-IDF), z wyższymi wynikami przechodzącymi do dokumentów o większej lub silniejszej dopasowaniu w okresie wyszukiwania.

Zakres "@search.score" jest niezwiązany lub 0 do (ale nie obejmuje) 1,00 dla starszych usług.

W przypadku jednego z algorytmów wynik "@search.score" równy 1,00 wskazuje nieznakowany lub niesklasowany zestaw wyników, w którym wynik 1,0 jest jednolity we wszystkich wynikach. Wyniki bez podkreślenia występują, gdy formularz zapytania jest wyszukiwaniem rozmytym, symbolem wieloznacznymi lub kwerendami regularnymi lub pustym wyszukiwaniem (search=*). Jeśli musisz narzucić strukturę klasyfikacji dla wyników bez podkreślenia, rozważ $orderby wyrażenie, aby osiągnąć ten cel.

Order by the semantic reranker (Kolejność według semantycznego rerankera)

Jeśli używasz klasyfikacji semantycznej, wyrażenie "@search.rerankerScore" określa kolejność sortowania wyników.

Zakres "@search.rerankerScore" wynosi od 1 do 4,00, gdzie wyższy wynik wskazuje silniejszy mecz semantyczny.

Zamawianie za pomocą $orderby

Jeśli spójne porządkowanie jest wymaganiem aplikacji, możesz zdefiniować $orderby wyrażenie w polu. Do zamawiania wyników mogą służyć tylko pola indeksowane jako "sortowalne".

Pola często używane w klasyfikacji $orderby , dacie i lokalizacji. Filtrowanie według lokalizacji wymaga, aby wyrażenie filtru geo.distance() wywołuje funkcję oprócz nazwy pola.

Pola liczbowe (Edm.Double, Edm.Int32, Edm.Int64) są sortowane w kolejności liczbowej (na przykład 1, 2, 10, 11, 20).

Pola ciągów (podpola Edm.String, Edm.ComplexType) są sortowane w kolejności sortowania ASCII lub w kolejności sortowania Unicode w zależności od języka. Nie można sortować kolekcji dowolnego typu.

  • Zawartość liczbowa w polach ciągów jest sortowana alfabetycznie (1, 10, 11, 2, 20).

  • Wielkie litery ciągi są sortowane przed małymi literami (APPLE, Apple, BANANA, Banana, Apple, apple, banana). Normalizator tekstu można przypisać do wstępnego przetwarzania tekstu przed sortowaniem w celu zmiany tego zachowania. Użycie małego tokenizatora w polu nie będzie miało wpływu na zachowanie sortowania, ponieważ usługa Azure AI Search sortuje w nieanalizowanej kopii pola.

  • Ciągi prowadzące z diakrytycznymi pojawiają się ostatnio (Äpfel, Öffnen, Üben)

Zwiększanie istotności przy użyciu profilu oceniania

Innym podejściem, które promuje spójność zamówień, jest użycie niestandardowego profilu oceniania. Profile oceniania zapewniają większą kontrolę nad klasyfikowaniem elementów w wynikach wyszukiwania z możliwością zwiększania dopasowań znalezionych w określonych polach. Dodatkowa logika oceniania może pomóc zastąpić drobne różnice między replikami, ponieważ wyniki wyszukiwania dla każdego dokumentu są bardziej oddalone. Zalecamy algorytm klasyfikowania dla tego podejścia.

Wyróżnianie trafień

Wyróżnianie trafień odnosi się do formatowania tekstu (na przykład pogrubienia lub żółtego wyróżnienia) stosowanego do pasujących terminów w wyniku, co ułatwia wykrycie dopasowania. Wyróżnianie jest przydatne w przypadku dłuższych pól zawartości, takich jak pole opisu, gdzie dopasowanie nie jest od razu oczywiste.

Zwróć uwagę, że wyróżnianie jest stosowane do poszczególnych terminów. Nie ma możliwości wyróżniania zawartości całego pola. Jeśli chcesz wyróżnić frazę, musisz podać pasujące terminy (lub frazę) w ciągu zapytania ujętego w cudzysłów. Ta technika została szczegółowo opisana w tej sekcji.

Instrukcje wyróżniania trafień są udostępniane w żądaniu zapytania. Zapytania wyzwalające rozszerzanie zapytań w a aparatu, takie jak wyszukiwanie rozmyte i wieloznaczne, mają ograniczoną obsługę wyróżniania trafień.

Wymagania dotyczące wyróżniania trafień

  • Pola muszą być Edm.String lub Collection(Edm.String)
  • Pola muszą być przypisywane do wyszukiwania

Określanie wyróżniania w żądaniu

Aby zwrócić wyróżnione terminy, dołącz parametr "wyróżnij" w żądaniu zapytania. Parametr jest ustawiony na rozdzielaną przecinkami listę pól.

Domyślnie znacznik formatu to <em>, ale można zastąpić tag przy użyciu parametrów highlightPreTag i highlightPostTag . Kod klienta obsługuje odpowiedź (na przykład zastosowanie czcionki pogrubionej lub żółtego tła).

POST /indexes/good-books/docs/search?api-version=2020-06-30 
    {  
      "search": "divine secrets",  
      "highlight": "title, original_title",
      "highlightPreTag": "<b>",
      "highlightPostTag": "</b>"
    }

Domyślnie usługa Azure AI Search zwraca maksymalnie pięć wyróżnień na pole. Tę liczbę można dostosować, dołączając kreskę, po której następuje liczba całkowita. Na przykład "highlight": "description-10" zwraca maksymalnie 10 wyróżnionych terminów dotyczących dopasowywania zawartości w polu "description".

Wyróżnione wyniki

Po dodaniu wyróżniania do zapytania odpowiedź zawiera "@search.highlights" dla każdego wyniku, dzięki czemu kod aplikacji może być przeznaczony dla tej struktury. Lista pól określonych dla "wyróżnienia" znajduje się w odpowiedzi.

W wyszukiwaniu słów kluczowych każdy termin jest skanowany niezależnie. Zapytanie dotyczące "boskich wpisów tajnych" zwróci dopasowania do dowolnego dokumentu zawierającego dowolny termin.

Zrzut ekranu przedstawiający wyróżnianie zapytania frazy.

Wyróżnianie wyszukiwania słów kluczowych

W wyróżnionym polu formatowanie jest stosowane do całych terminów. Na przykład na meczu z "The Divine Secrets of the Ya-Ya Sisterhood" formatowanie jest stosowane do każdego terminu oddzielnie, mimo że są one kolejne.

"@odata.count": 39,
"value": [
    {
        "@search.score": 19.593246,
        "@search.highlights": {
            "original_title": [
                "<em>Divine</em> <em>Secrets</em> of the Ya-Ya Sisterhood"
            ],
            "title": [
                "<em>Divine</em> <em>Secrets</em> of the Ya-Ya Sisterhood"
            ]
        },
        "original_title": "Divine Secrets of the Ya-Ya Sisterhood",
        "title": "Divine Secrets of the Ya-Ya Sisterhood"
    },
    {
        "@search.score": 12.779835,
        "@search.highlights": {
            "original_title": [
                "<em>Divine</em> Madness"
            ],
            "title": [
                "<em>Divine</em> Madness (Cherub, #5)"
            ]
        },
        "original_title": "Divine Madness",
        "title": "Divine Madness (Cherub, #5)"
    },
    {
        "@search.score": 12.62534,
        "@search.highlights": {
            "original_title": [
                "Grave <em>Secrets</em>"
            ],
            "title": [
                "Grave <em>Secrets</em> (Temperance Brennan, #5)"
            ]
        },
        "original_title": "Grave Secrets",
        "title": "Grave Secrets (Temperance Brennan, #5)"
    }
]

Wyróżnianie wyszukiwania fraz

KtoTo formatowanie terminów ma zastosowanie nawet w wyszukiwaniu fraz, gdzie wiele terminów jest ujęta w podwójny cudzysłów. Poniższy przykład jest tym samym zapytaniem, z tą różnicą, że "boskie wpisy tajne" są przesyłane jako fraza ujęta w cudzysłów (niektórzy klienci REST wymagają ucieczki od znaków cudzysłowu wewnętrznego z ukośnikiem \"odwrotnym):

POST /indexes/good-books/docs/search?api-version=2020-06-30 
    {  
      "search": "\"divine secrets\"",,
      "select": "title,original_title",
      "highlight": "title",
      "highlightPreTag": "<b>",
      "highlightPostTag": "</b>",
      "count": true
    }

Ponieważ kryteria mają teraz oba terminy, w indeksie wyszukiwania znajduje się tylko jedno dopasowanie. Odpowiedź na powyższe zapytanie wygląda następująco:

{
    "@odata.count": 1,
    "value": [
        {
            "@search.score": 19.593246,
            "@search.highlights": {
                "title": [
                    "<b>Divine</b> <b>Secrets</b> of the Ya-Ya Sisterhood"
                ]
            },
            "original_title": "Divine Secrets of the Ya-Ya Sisterhood",
            "title": "Divine Secrets of the Ya-Ya Sisterhood"
        }
    ]
}

Wyróżnianie fraz dla starszych usług

usługa wyszukiwania, które zostały utworzone przed 15 lipca 2020 r., implementują inne środowisko wyróżniania dla zapytań fraz.

W poniższych przykładach przyjęto założenie, że ciąg zapytania zawiera frazę "super bowl" zawierającą cudzysłów. Przed lipcem 2020 r. wyróżniono dowolny termin w frazie:

"@search.highlights": {
    "sentence": [
        "The <em>super</em> <em>bowl</em> is <em>super</em> awesome with a <em>bowl</em> of chips"
   ]

W przypadku usług wyszukiwania utworzonych po lipcu 2020 r. w ciągu "@search.highlights" będą zwracane tylko frazy zgodne z pełnym zapytaniem frazy:

"@search.highlights": {
    "sentence": [
        "The <em>super</em> <em>bowl</em> is super awesome with a bowl of chips"
   ]

Następne kroki

Aby szybko wygenerować stronę wyszukiwania dla klienta, rozważ następujące opcje:

  • Generator aplikacji w portalu tworzy stronę HTML z paskiem wyszukiwania, nawigacją aspektową i obszarem wyników zawierającym obrazy.

  • Dodawanie wyszukiwania do aplikacji ASP.NET Core (MVC) to samouczek i przykład kodu, który tworzy funkcjonalnego klienta.

  • Dodawanie wyszukiwania do aplikacji internetowych to samouczek i przykład kodu, który używa bibliotek Języka JavaScript platformy React na potrzeby środowiska użytkownika. Aplikacja jest wdrażana przy użyciu usługi Azure Static Web Apps.