Relációs SQL-adatok modellezése importáláshoz és indexeléshez az Azure AI Searchben
Az Azure AI Search egy lapos sorkészletet fogad el az indexelési folyamat bemeneteként. Ha a forrásadatok egy SQL Server-relációs adatbázis csatlakoztatott tábláiból származnak, ez a cikk bemutatja, hogyan hozhat létre sorkészletet, és hogyan modellezhet szülő-gyermek kapcsolatot egy Azure AI Search-indexben.
Illusztrációként egy hipotetikus hoteladatbázisra hivatkozunk, amely demoadatokon alapul. Tegyük fel, hogy az adatbázis egy Hotels$
50 szállodát tartalmazó táblából és egy Rooms$
különböző típusú, díjszabással és felszereltséggel rendelkező táblázatból áll, összesen 750 szoba számára. A táblák között egy-a-többhöz kapcsolat áll fenn. A megközelítésünkben egy nézet 50 sort, szállodánként egy sort ad vissza, és az egyes sorokba beágyazott kapcsolódó helyiségrészleteket tartalmaz.
A denormalizált adatok problémája
Az egy-a-többhöz kapcsolatok használatának egyik kihívása, hogy az összekapcsolt táblákra épülő standard lekérdezések denormalizált adatokat adnak vissza, ami nem működik jól az Azure AI Search-forgatókönyvekben. Tekintse meg az alábbi példát, amely a szállodákhoz és szobákhoz csatlakozik.
SELECT * FROM Hotels$
INNER JOIN Rooms$
ON Rooms$.HotelID = Hotels$.HotelID
A lekérdezés eredményei az összes Hotel mezőt, majd az összes Szoba mezőt visszaadják, és az előzetes szállodai adatok ismétlődnek az egyes szobaértékek esetében.
Bár ez a lekérdezés sikeres a felületen (az összes adatot egy sík sorhalmazban adja meg), nem sikerül a megfelelő dokumentumszerkezetet biztosítani a várt keresési élményhez. Az indexelés során az Azure AI Search minden betöltendő sorhoz létrehoz egy keresési dokumentumot. Ha a keresési dokumentumok úgy néznek ki, mint a fenti eredmények, akkor észlelte volna duplikáltak - hét külön dokumentumot az Old Century Hotel egyedül. A "floridai szállodákra" vonatkozó lekérdezés hét találatot ad vissza az Old Century Hotelre vonatkozóan, a többi releváns szállodát pedig mélyen a keresési eredményekbe.
A szállodánkénti egy dokumentum várható élményének eléréséhez meg kell adnia egy sorkészletet a megfelelő részletességgel, de teljes információkkal. Ez a cikk bemutatja, hogyan.
Beágyazott JSON-t visszaadó lekérdezés definiálása
A várt keresési élmény biztosításához az adatkészletnek egy sorból kell állnia az Azure AI Search minden egyes keresési dokumentumához. A példánkban minden szállodához egy sort szeretnénk, de azt is szeretnénk, hogy a felhasználók más, számukra fontos helyiségekkel kapcsolatos mezőkre is rákereshessenek, például az éjszakai díjszabásra, az ágyak méretére és számára, vagy a strandra, amelyek mindegyike egy szobarészlet részét képezi.
A megoldás az, hogy beágyazott JSON-ként rögzíti a helyiség részleteit, majd beszúrja a JSON-struktúrát egy nézetben lévő mezőbe, ahogyan a második lépésben látható.
Tegyük fel, hogy két csatlakoztatott táblája van,
Hotels$
amelyekRooms$
50 szálloda és 750 szoba adatait tartalmazzák, és a HotelID mezőhöz csatlakoznak. Ezek a táblázatok egyenként 50 szállodát és 750 kapcsolódó szobát tartalmaznak.CREATE TABLE [dbo].[Hotels$]( [HotelID] [nchar](10) NOT NULL, [HotelName] [nvarchar](255) NULL, [Description] [nvarchar](max) NULL, [Description_fr] [nvarchar](max) NULL, [Category] [nvarchar](255) NULL, [Tags] [nvarchar](255) NULL, [ParkingIncluded] [float] NULL, [SmokingAllowed] [float] NULL, [LastRenovationDate] [smalldatetime] NULL, [Rating] [float] NULL, [StreetAddress] [nvarchar](255) NULL, [City] [nvarchar](255) NULL, [State] [nvarchar](255) NULL, [ZipCode] [nvarchar](255) NULL, [GeoCoordinates] [nvarchar](255) NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO CREATE TABLE [dbo].[Rooms$]( [HotelID] [nchar](10) NULL, [Description] [nvarchar](255) NULL, [Description_fr] [nvarchar](255) NULL, [Type] [nvarchar](255) NULL, [BaseRate] [float] NULL, [BedOptions] [nvarchar](255) NULL, [SleepsCount] [float] NULL, [SmokingAllowed] [float] NULL, [Tags] [nvarchar](255) NULL ) ON [PRIMARY] GO
Hozzon létre egy nézetet a szülőtábla (
SELECT * from dbo.Hotels$
) összes mezőjéből, és adjon hozzá egy új Helyiség mezőt, amely egy beágyazott lekérdezés kimenetét tartalmazza. A FOR JSON AUTO záradék a kimenet JSON-ként való felépítéséreSELECT * from dbo.Rooms$
.CREATE VIEW [dbo].[HotelRooms] AS SELECT *, (SELECT * FROM dbo.Rooms$ WHERE dbo.Rooms$.HotelID = dbo.Hotels$.HotelID FOR JSON AUTO) AS Rooms FROM dbo.Hotels$ GO
Az alábbi képernyőképen az eredményül kapott nézet látható, alul a Szobák nvarchar mezővel. A Szobák mező csak a HotelRooms nézetben létezik.
Futtassa
SELECT * FROM dbo.HotelRooms
a sorkészlet lekéréséhez. Ez a lekérdezés 50 sort ad vissza, egy szállodánként, és a hozzá tartozó szobainformációkat JSON-gyűjteményként.
Ez a sorkészlet készen áll az Azure AI Searchbe való importálásra.
Feljegyzés
Ez a megközelítés feltételezi, hogy a beágyazott JSON az SQL Server maximális oszlopméretkorlátja alatt van.
Összetett gyűjtemény használata az egy-a-többhöz kapcsolat "több" oldalához
Az Azure AI Search oldalán hozzon létre egy indexsémát, amely beágyazott JSON használatával modellezi az egy-a-többhöz kapcsolatot. Az előző szakaszban létrehozott eredményhalmaz általában a következőben megadott indexsémának felel meg (a rövidség kedvéért kivágunk néhány mezőt).
Az alábbi példa hasonló az összetett adattípusok modellezése című példához. A szobák struktúrája, amely a cikk középpontjában áll, egy hotel nevű index mezőgyűjteményében található. Ez a példa egy összetett címtípust is bemutat, amely abban különbözik a Szobáktól, hogy rögzített elemekből áll, szemben a gyűjteményben engedélyezett elemek többszörös, tetszőleges számával.
{
"name": "hotels",
"fields": [
{ "name": "HotelId", "type": "Edm.String", "key": true, "filterable": true },
{ "name": "HotelName", "type": "Edm.String", "searchable": true, "filterable": false },
{ "name": "Description", "type": "Edm.String", "searchable": true, "analyzer": "en.lucene" },
{ "name": "Description_fr", "type": "Edm.String", "searchable": true, "analyzer": "fr.lucene" },
{ "name": "Category", "type": "Edm.String", "searchable": true, "filterable": true, "facetable": true },
{ "name": "ParkingIncluded", "type": "Edm.Boolean", "filterable": true, "facetable": true },
{ "name": "Tags", "type": "Collection(Edm.String)", "searchable": true, "filterable": true, "facetable": true },
{ "name": "Address", "type": "Edm.ComplexType",
"fields": [
{ "name": "StreetAddress", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false, "searchable": true },
{ "name": "City", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true },
{ "name": "StateProvince", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }
]
},
{ "name": "Rooms", "type": "Collection(Edm.ComplexType)",
"fields": [
{ "name": "Description", "type": "Edm.String", "searchable": true, "analyzer": "en.lucene" },
{ "name": "Description_fr", "type": "Edm.String", "searchable": true, "analyzer": "fr.lucene" },
{ "name": "Type", "type": "Edm.String", "searchable": true },
{ "name": "BaseRate", "type": "Edm.Double", "filterable": true, "facetable": true },
{ "name": "BedOptions", "type": "Edm.String", "searchable": true, "filterable": true, "facetable": false },
{ "name": "SleepsCount", "type": "Edm.Int32", "filterable": true, "facetable": true },
{ "name": "SmokingAllowed", "type": "Edm.Boolean", "filterable": true, "facetable": false},
{ "name": "Tags", "type": "Edm.Collection", "searchable": true }
]
}
]
}
Az előző eredménykészlet és a fenti indexséma alapján a sikeres indexelési művelethez minden szükséges összetevővel rendelkezik. Az összesimított adatkészlet megfelel az indexelési követelményeknek, de megőrzi a részletes információkat. Az Azure AI Search-indexben a keresési eredmények könnyen hotelalapú entitásokba kerülnek, miközben megőrzik az egyes szobák és attribútumaik kontextusát.
Összetett típusú almezők arculati viselkedése
A szülővel rendelkező mezőket, például a Cím és a Szobák alatti mezőket almezőknek nevezzük. Bár hozzárendelhet egy "facetable" attribútumot egy almezőhöz, az aspektusok száma mindig a törzsdokumentumhoz tartozik.
Az olyan összetett típusok esetében, mint a Cím, ahol csak egy "Cím/Város" vagy "Cím/stateProvince" szerepel a dokumentumban, a jellemző viselkedése a várt módon működik. A szobák esetében azonban, ahol az egyes törzsdokumentumokhoz több aldokumentum tartozik, az aspektusok száma félrevezető lehet.
Ahogy a modell összetett típusaiban is említettük: "az eredményben visszaadott dokumentumszámokat a szülődokumentum (szálloda) számítja ki, nem pedig az összetett gyűjtemények (szobák) aldokumentumai. Tegyük fel például, hogy egy szálloda 20 "suite" típusú szobával rendelkezik. Tekintettel a facet=Rooms/Type aspektusparaméterre, a aspektusok száma a szálloda esetében egy, a szobáknál nem 20."
Következő lépések
A saját adatkészletével az Adatok importálása varázslóval hozhatja létre és töltheti be az indexet. A varázsló észleli a beágyazott JSON-gyűjteményt, például a Szobákban található gyűjteményt, és egy összetett típusú gyűjteményt tartalmazó indexsémára következtet.
Az Adatok importálása varázsló alapvető lépéseit az alábbi rövid útmutatóban ismerheti meg.