Gebruik de 'eenvoudige' zoeksyntaxis in Azure Cognitive Search

In Azure Cognitive Search roept de eenvoudige querysyntaxis de standaardqueryparser aan voor zoeken in volledige tekst. De parser is snel en verwerkt veelvoorkomende scenario's, waaronder zoeken in volledige tekst, gefilterde en facetzoekopdrachten en zoeken naar voorvoegsels. In dit artikel worden voorbeelden gebruikt om eenvoudig syntaxisgebruik in een REST API-aanvraag (Zoekdocumenten) te illustreren.

Notitie

Een alternatieve querysyntaxis is Full Lucene, die complexere querystructuren ondersteunt, zoals zoeken met fuzzy en jokertekens. Zie De volledige Lucene-syntaxis gebruiken voor meer informatie en voorbeelden.

Voorbeeldindex hotels

De volgende query's zijn gebaseerd op de hotels-sample-index, die u kunt maken door de instructies in deze quickstart te volgen.

Voorbeeldquery's worden geformuleerd met behulp van de REST API- en POST-aanvragen. U kunt ze plakken en uitvoeren in Postman of een andere webclient.

Aanvraagheaders moeten de volgende waarden hebben:

Sleutel Waarde
Content-Type application/json
api-key <your-search-service-api-key>, query of beheersleutel

URI-parameters moeten uw zoekservice-eindpunt bevatten met de indexnaam, docs-verzamelingen, zoekopdracht en API-versie, vergelijkbaar met het volgende voorbeeld:

https://{{service-name}}.search.windows.net/indexes/hotels-sample-index/docs/search?api-version=2020-06-30

De aanvraagbody moet worden gevormd als geldige JSON:

{
    "search": "*",
    "queryType": "simple",
    "select": "HotelId, HotelName, Category, Tags, Description",
    "count": true
}
  • 'search' ingesteld op * is een niet-opgegeven query, gelijk aan null of lege zoekopdracht. Het is niet erg handig, maar het is de eenvoudigste zoekopdracht die u kunt uitvoeren en alle velden die u kunt ophalen in de index, met alle waarden.

  • 'queryType' ingesteld op 'eenvoudig' is de standaardinstelling en kan worden weggelaten, maar het is opgenomen om nog meer te bevestigen dat de queryvoorbeelden in dit artikel worden uitgedrukt in de eenvoudige syntaxis.

  • 'selecteren' ingesteld op een door komma's gescheiden lijst met velden wordt gebruikt voor het samenstellen van zoekresultaten, inclusief alleen de velden die nuttig zijn in de context van zoekresultaten.

  • 'count' retourneert het aantal documenten dat voldoet aan de zoekcriteria. Bij een lege zoekreeks worden alle documenten in de index geteld (50 in het geval van hotels-sample-index).

Zoeken in volledige tekst kan een willekeurig aantal zelfstandige termen of tussen aanhalingstekens zijn, met of zonder booleaanse operatoren.

POST /indexes/hotel-samples-index/docs/search?api-version=2020-06-30
{
    "search": "pool spa +airport",
    "searchMode": "any",
    "queryType": "simple",
    "select": "HotelId, HotelName, Category, Description",
    "count": true
}

Een zoekopdracht op trefwoorden die bestaat uit belangrijke termen of woordgroepen werkt meestal het beste. Tekenreeksvelden ondergaan tekstanalyse tijdens het indexeren en uitvoeren van query's, waarbij niet-essentiële woorden zoals 'de', 'en', 'it' worden verwijderd. Als u wilt zien hoe een queryreeks in de index wordt getokeniseerd, geeft u de tekenreeks in een aanroep Tekst analyseren door aan de index.

De parameter 'searchMode' bepaalt de precisie en relevante overeenkomsten. Als u meer overeenkomsten wilt, gebruikt u de standaardwaarde 'any', die een resultaat retourneert als een deel van de querytekenreeks overeenkomt. Als u de voorkeur geeft aan precisie, waarbij alle delen van de tekenreeks overeenkomen, wijzigt u searchMode in 'alles'. Probeer de bovenstaande query op beide manieren om te zien hoe searchMode het resultaat wijzigt.

Het antwoord voor de query 'pool spa +airport' moet er ongeveer uitzien als in het volgende voorbeeld, kortheidshalve bijgesneden.

"@odata.count": 6,
"value": [
    {
        "@search.score": 7.3617697,
        "HotelId": "21",
        "HotelName": "Nova Hotel & Spa",
        "Description": "1 Mile from the airport.  Free WiFi, Outdoor Pool, Complimentary Airport Shuttle, 6 miles from the beach & 10 miles from downtown.",
        "Category": "Resort and Spa",
        "Tags": [
            "pool",
            "continental breakfast",
            "free parking"
        ]
    },
    {
        "@search.score": 2.5560288,
        "HotelId": "25",
        "HotelName": "Scottish Inn",
        "Description": "Newly Redesigned Rooms & airport shuttle.  Minutes from the airport, enjoy lakeside amenities, a resort-style pool & stylish new guestrooms with Internet TVs.",
        "Category": "Luxury",
        "Tags": [
            "24-hour front desk service",
            "continental breakfast",
            "free wifi"
        ]
    },
    {
        "@search.score": 2.2988036,
        "HotelId": "35",
        "HotelName": "Suites At Bellevue Square",
        "Description": "Luxury at the mall.  Located across the street from the Light Rail to downtown.  Free shuttle to the mall and airport.",
        "Category": "Resort and Spa",
        "Tags": [
            "continental breakfast",
            "air conditioning",
            "24-hour front desk service"
        ]
    }

Let op de zoekscore in het antwoord. Dit is de relevantiescore van de overeenkomst. Standaard retourneert een zoekservice de top 50 overeenkomsten op basis van deze score.

Uniforme scores van '1,0' treden op wanneer er geen rangschikking is, omdat de zoekopdracht geen zoekopdracht in volledige tekst was of omdat er geen criteria zijn opgegeven. In een lege zoekopdracht (search=*) komen rijen bijvoorbeeld in willekeurige volgorde terug. Wanneer u werkelijke criteria opneemt, ziet u dat zoekscores veranderen in zinvolle waarden.

Voorbeeld 2: Opzoeken op id

Wanneer u zoekresultaten in een query retourneert, is een logische volgende stap het opgeven van een detailpagina met meer velden uit het document. In dit voorbeeld ziet u hoe u één document retourneert met behulp van Opzoekdocument door de document-id door te geven.

GET /indexes/hotels-sample-index/docs/41?api-version=2020-06-30

Alle documenten hebben een unieke id. Als u de portal gebruikt, selecteert u de index op het tabblad Indexen en bekijkt u de velddefinities om te bepalen welk veld de sleutel is. Met behulp van REST retourneert de aanroep Index ophalen de indexdefinitie in de hoofdtekst van het antwoord.

Het antwoord op de bovenstaande query bestaat uit het document waarvan de sleutel 41 is. Elk veld dat is gemarkeerd als 'ophaalbaar' in de indexdefinitie, kan worden geretourneerd in de zoekresultaten en worden weergegeven in uw app.

{
    "HotelId": "41",
    "HotelName": "Ocean Air Motel",
    "Description": "Oceanfront hotel overlooking the beach features rooms with a private balcony and 2 indoor and outdoor pools. Various shops and art entertainment are on the boardwalk, just steps away.",
    "Description_fr": "L'hôtel front de mer surplombant la plage dispose de chambres avec balcon privé et 2 piscines intérieures et extérieures. Divers commerces et animations artistiques sont sur la promenade, à quelques pas.",
    "Category": "Budget",
    "Tags": [
        "pool",
        "air conditioning",
        "bar"
    ],
    "ParkingIncluded": true,
    "LastRenovationDate": "1951-05-10T00:00:00Z",
    "Rating": 3.5,
    "Location": {
        "type": "Point",
        "coordinates": [
            -157.846817,
            21.295841
        ],
        "crs": {
            "type": "name",
            "properties": {
                "name": "EPSG:4326"
            }
        }
    },
    "Address": {
        "StreetAddress": "1450 Ala Moana Blvd 2238 Ala Moana Ctr",
        "City": "Honolulu",
        "StateProvince": "HI",
        "PostalCode": "96814",
        "Country": "USA"
    },

Voorbeeld 3: Filteren op tekst

Filtersyntaxis is een OData-expressie die u op zichzelf of met 'zoeken' kunt gebruiken. Samen gebruikt, wordt 'filter' eerst toegepast op de hele index en vervolgens wordt de zoekopdracht uitgevoerd op de resultaten van het filter. Filters zijn dus nuttig om de resultaten van de zoekopdracht te verbeteren, doordat het aantal documenten dat moet worden doorzocht, wordt verminderd.

Filters kunnen worden gedefinieerd voor elk veld dat is gemarkeerd als 'filterbaar' in de indexdefinitie. Voor hotels-sample-index bevatten filterbare velden Categorie, Tags, ParkerenIncluded, Beoordeling en de meeste adresvelden.

POST /indexes/hotels-sample-index/docs/search?api-version=2020-06-30
{
    "search": "art tours",
    "queryType": "simple",
    "filter": "Category eq 'Resort and Spa'",
    "select": "HotelId,HotelName,Description,Category",
    "count": true
}

Het antwoord op de bovenstaande query is gericht op alleen de hotels die zijn gecategoriseerd als 'Rapport en spa', waaronder de termen 'art' of 'tours'. In dit geval is er slechts één overeenkomst.

{
    "@search.score": 2.8576312,
    "HotelId": "31",
    "HotelName": "Santa Fe Stay",
    "Description": "Nestled on six beautifully landscaped acres, located 2 blocks from the Plaza. Unwind at the spa and indulge in art tours on site.",
    "Category": "Resort and Spa"
}

Voorbeeld 4: Filterfuncties

Filterexpressies kunnen de functies 'search.ismatch' en 'search.ismatchscoring' bevatten, zodat u een zoekquery in het filter kunt maken. Deze filterexpressie gebruikt een jokerteken op gratis om voorzieningen te selecteren, waaronder gratis wifi, gratis parkeren, enzovoort.

POST /indexes/hotels-sample-index/docs/search?api-version=2020-06-30
  {
    "search": "",
    "filter": "search.ismatch('free*', 'Tags', 'full', 'any')",
    "select": "HotelId, HotelName, Category, Description",
    "count": true
  }

Het antwoord op de bovenstaande query komt overeen met 19 hotels die gratis voorzieningen bieden. U ziet dat de zoekscore een uniforme '1,0' is in de resultaten. Dit komt doordat de zoekexpressie null of leeg is, wat resulteert in exacte filterovereenkomsten, maar geen zoekopdracht in volledige tekst. Relevantiescores worden alleen geretourneerd bij zoekopdrachten in volledige tekst. Als u filters zonder 'zoeken' gebruikt, moet u ervoor zorgen dat u voldoende sorteerbare velden hebt, zodat u de zoekrang kunt bepalen.

"@odata.count": 19,
"value": [
    {
        "@search.score": 1.0,
        "HotelId": "31",
        "HotelName": "Santa Fe Stay",
        "Tags": [
            "view",
            "restaurant",
            "free parking"
        ]
    },
    {
        "@search.score": 1.0,
        "HotelId": "27",
        "HotelName": "Super Deluxe Inn & Suites",
        "Tags": [
            "bar",
            "free wifi"
        ]
    },
    {
        "@search.score": 1.0,
        "HotelId": "39",
        "HotelName": "Whitefish Lodge & Suites",
        "Tags": [
            "continental breakfast",
            "free parking",
            "free wifi"
        ]
    },
    {
        "@search.score": 1.0,
        "HotelId": "11",
        "HotelName": "Regal Orb Resort & Spa",
        "Tags": [
            "free wifi",
            "restaurant",
            "24-hour front desk service"
        ]
    },

Voorbeeld 5: Bereikfilters

Bereikfiltering wordt ondersteund via filterexpressies voor elk gegevenstype. In de volgende voorbeelden ziet u numerieke en tekenreeksbereiken. Gegevenstypen zijn belangrijk in bereikfilters en werken het beste wanneer numerieke gegevens zich in numerieke velden bevinden en tekenreeksgegevens in tekenreeksvelden. Numerieke gegevens in tekenreeksvelden zijn niet geschikt voor bereiken omdat numerieke tekenreeksen niet vergelijkbaar zijn.

De volgende query is een numeriek bereik. In hotels-sample-index is het enige filterbare numerieke veld Rating.

POST /indexes/hotels-sample-index/docs/search?api-version=2020-06-30
{
    "search": "*",
    "filter": "Rating ge 2 and Rating lt 4",
    "select": "HotelId, HotelName, Rating",
    "orderby": "Rating desc",
    "count": true
}

Het antwoord voor deze query moet er ongeveer uitzien als in het volgende voorbeeld, kortheidshalve bijgesneden.

"@odata.count": 27,
"value": [
    {
        "@search.score": 1.0,
        "HotelId": "22",
        "HotelName": "Stone Lion Inn",
        "Rating": 3.9
    },
    {
        "@search.score": 1.0,
        "HotelId": "25",
        "HotelName": "Scottish Inn",
        "Rating": 3.8
    },
    {
        "@search.score": 1.0,
        "HotelId": "2",
        "HotelName": "Twin Dome Motel",
        "Rating": 3.6
    }

De volgende query is een bereikfilter op een tekenreeksveld (Address/StateProvince):

POST /indexes/hotels-sample-index/docs/search?api-version=2020-06-30
{
    "search": "*",
    "filter": "Address/StateProvince ge 'A*' and Address/StateProvince lt 'D*'",
    "select": "HotelId, HotelName, Address/StateProvince",
    "count": true
}

Het antwoord voor deze query moet er ongeveer uitzien als in het onderstaande voorbeeld, kortheidshalve bijgesneden. In dit voorbeeld is het niet mogelijk om te sorteren op StateProvince, omdat het veld niet is toegewezen als 'sorteerbaar' in de indexdefinitie.

"@odata.count": 9,
"value": [
    {
        "@search.score": 1.0,
        "HotelId": "9",
        "HotelName": "Smile Hotel",
        "Address": {
            "StateProvince": "CA "
        }
    },
    {
        "@search.score": 1.0,
        "HotelId": "39",
        "HotelName": "Whitefish Lodge & Suites",
        "Address": {
            "StateProvince": "CO"
        }
    },
    {
        "@search.score": 1.0,
        "HotelId": "7",
        "HotelName": "Countryside Resort",
        "Address": {
            "StateProvince": "CA "
        }
    },

De index hotels-sample bevat een veld Locatie met breedte- en lengtegraadcoördinaten. In dit voorbeeld wordt de functie geo.distance gebruikt die filtert op documenten binnen de omtrek van een beginpunt, tot een willekeurige afstand (in kilometers) die u opgeeft. U kunt de laatste waarde in de query (10) aanpassen om het oppervlak van de query te verkleinen of vergroten.

POST /indexes/v/docs/search?api-version=2020-06-30
{
    "search": "*",
    "filter": "geo.distance(Location, geography'POINT(-122.335114 47.612839)') le 10",
    "select": "HotelId, HotelName, Address/City, Address/StateProvince",
    "count": true
}

Het antwoord op deze query retourneert alle hotels binnen een afstand van 10 kilometer van de opgegeven coördinaten:

{
    "@odata.count": 3,
    "value": [
        {
            "@search.score": 1.0,
            "HotelId": "45",
            "HotelName": "Arcadia Resort & Restaurant",
            "Address": {
                "City": "Seattle",
                "StateProvince": "WA"
            }
        },
        {
            "@search.score": 1.0,
            "HotelId": "24",
            "HotelName": "Gacc Capital",
            "Address": {
                "City": "Seattle",
                "StateProvince": "WA"
            }
        },
        {
            "@search.score": 1.0,
            "HotelId": "16",
            "HotelName": "Double Sanctuary Resort",
            "Address": {
                "City": "Seattle",
                "StateProvince": "WA"
            }
        }
    ]
}

Voorbeeld 7: Booleaanse waarden met searchMode

Eenvoudige syntaxis ondersteunt booleaanse operatoren in de vorm van tekens (+, -, |) ter ondersteuning van de querylogica AND, OR en NOT. Booleaanse zoekopdrachten gedragen zich zoals u zou verwachten, met enkele opmerkelijke uitzonderingen.

In eerdere voorbeelden is de parameter 'searchMode' geïntroduceerd als een mechanisme voor het beïnvloeden van precisie en relevante overeenkomsten, waarbij 'searchMode=any' de voorkeur geeft aan terughalen (een document dat voldoet aan een van de criteria wordt beschouwd als een overeenkomst) en 'searchMode=all' die de voorkeur geeft aan precisie (alle criteria moeten worden vergeleken in een document).

In de context van een Booleaanse zoekopdracht kan de standaard 'searchMode=any' verwarrend zijn als u een query stapelt met meerdere operators en breder wordt in plaats van smallere resultaten. Dit geldt met name voor NOT, waarbij de resultaten alle documenten bevatten die geen specifieke term of woordgroep bevatten.

In het volgende voorbeeld ziet u een illustratie. Als u de volgende query uitvoert met searchMode (any), worden er 42 documenten geretourneerd: documenten met de term 'restaurant', plus alle documenten die niet de zin 'airconditioning' hebben.

U ziet dat er geen ruimte is tussen de booleaanse operator (-) en de woordgroep 'airconditioning'.

POST /indexes/hotels-sample-index/docs/search?api-version=2020-06-30
{
    "search": "restaurant -\"air conditioning\"",
    "searchMode": "any",
    "searchFields": "Tags",
    "select": "HotelId, HotelName, Tags",
    "count": true
}

Als u wijzigt in searchMode=all, wordt een cumulatief effect op criteria afgedwongen en wordt een kleinere resultatenset (7 overeenkomsten) geretourneerd die bestaat uit documenten met de term 'restaurant', minus de documenten met de woordgroep 'airconditioning'.

Het antwoord voor deze query ziet er nu uit zoals in het volgende voorbeeld, kortheidshalve bijgesneden.

"@odata.count": 7,
"value": [
    {
        "@search.score": 2.5460577,
        "HotelId": "11",
        "HotelName": "Regal Orb Resort & Spa",
        "Tags": [
            "free wifi",
            "restaurant",
            "24-hour front desk service"
        ]
    },
    {
        "@search.score": 2.166792,
        "HotelId": "10",
        "HotelName": "Countryside Hotel",
        "Tags": [
            "24-hour front desk service",
            "coffee in lobby",
            "restaurant"
        ]
    },

Voorbeeld 8: Paging-resultaten

In eerdere voorbeelden hebt u geleerd over parameters die van invloed zijn op de samenstelling van zoekresultaten, waaronder 'selecteren' waarmee wordt bepaald welke velden zich in een resultaat bevinden, sorteervolgordes en hoe u een telling van alle overeenkomsten opneemt. Dit voorbeeld is een voortzetting van de samenstelling van zoekresultaten in de vorm van pagingsparameters waarmee u het aantal resultaten dat op een bepaalde pagina wordt weergegeven, batchgewijs kunt gebruiken.

Standaard retourneert een zoekservice de top 50 overeenkomsten. Als u het aantal overeenkomsten op elke pagina wilt beheren, gebruikt u 'top' om de grootte van de batch te definiëren en gebruikt u vervolgens 'overslaan' om volgende batches op te halen.

In het volgende voorbeeld wordt een filter- en sorteervolgorde gebruikt voor het veld Beoordeling (Classificatie is zowel filterbaar als sorteerbaar), omdat het gemakkelijker is om de effecten van paging op gesorteerde resultaten te zien. In een normale volledige zoekquery worden de belangrijkste overeenkomsten gerangschikt en weergegeven op '@search.score'.

POST /indexes/hotels-sample-index/docs/search?api-version=2020-06-30
{
    "search": "*",
    "filter": "Rating gt 4",
    "select": "HotelName, Rating",
    "orderby": "Rating desc",
    "top": "5",
    "count": true
}

Met de query worden 21 overeenkomende documenten gevonden, maar omdat u 'top' hebt opgegeven, retourneert het antwoord alleen de top vijf overeenkomsten, met beoordelingen die beginnen met 4,9 en eindigend bij 4,7 met 'Lady of the Lake B & '.

Als u de volgende 5 wilt ophalen, slaat u de eerste batch over:

POST /indexes/hotels-sample-index/docs/search?api-version=2020-06-30
{
    "search": "*",
    "filter": "Rating gt 4",
    "select": "HotelName, Rating",
    "orderby": "Rating desc",
    "top": "5",
    "skip": "5",
    "count": true
}

Het antwoord voor de tweede batch slaat de eerste vijf overeenkomsten over en retourneert de volgende vijf, beginnend met 'Pull'r Inn Motel'. Als u wilt doorgaan met extra batches, houdt u 'top' op 5 en gaat u vervolgens met 5 omhoog bij elke nieuwe aanvraag (skip=5, skip=10, skip=15, enzovoort).

"value": [
    {
        "@search.score": 1.0,
        "HotelName": "Pull'r Inn Motel",
        "Rating": 4.7
    },
    {
        "@search.score": 1.0,
        "HotelName": "Sublime Cliff Hotel",
        "Rating": 4.6
    },
    {
        "@search.score": 1.0,
        "HotelName": "Antiquity Hotel",
        "Rating": 4.5
    },
    {
        "@search.score": 1.0,
        "HotelName": "Nordick's Motel",
        "Rating": 4.5
    },
    {
        "@search.score": 1.0,
        "HotelName": "Winter Panorama Resort",
        "Rating": 4.5
    }
]

Volgende stappen

Nu u enige oefening hebt met de eenvoudige querysyntaxis, kunt u query's in code opgeven. In de volgende koppelingen wordt uitgelegd hoe u zoekquery's instelt met behulp van de Azure SDK's.

Aanvullende syntaxisreferenties, queryarchitectuur en voorbeelden vindt u in de volgende koppelingen: