You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: articles/search/index-sql-relational-data.md
+20-11Lines changed: 20 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,31 +8,31 @@ manager: nitinme
8
8
ms.author: heidist
9
9
ms.service: cognitive-search
10
10
ms.topic: how-to
11
-
ms.date: 02/08/2023
11
+
ms.date: 02/22/2023
12
12
---
13
13
# How to model relational SQL data for import and indexing in Azure Cognitive Search
14
14
15
15
Azure Cognitive Search accepts a flat rowset as input to the [indexing pipeline](search-what-is-an-index.md). If your source data originates from joined tables in a SQL Server relational database, this article explains how to construct the result set, and how to model a parent-child relationship in an Azure Cognitive Search index.
16
16
17
-
As an illustration, we'll refer to a hypothetical hotels database, based on [demo data](https://github.com/Azure-Samples/azure-search-sample-data/tree/master/hotels). Assume the database consists of a Hotels$ table with 50 hotels, and a Rooms$ table with rooms of varying types, rates, and amenities, for a total of 750 rooms. There is a one-to-many relationship between the tables. In our approach, a view will provide the query that returns 50 rows, one row per hotel, with associated room detail embedded into each row.
17
+
As an illustration, we refer to a hypothetical hotels database, based on [demo data](https://github.com/Azure-Samples/azure-search-sample-data/tree/master/hotels). Assume the database consists of a Hotels$ table with 50 hotels, and a Rooms$ table with rooms of varying types, rates, and amenities, for a total of 750 rooms. There's a one-to-many relationship between the tables. In our approach, a view provides the query that returns 50 rows, one row per hotel, with associated room detail embedded into each row.
18
18
19
19

20
20
21
21
## The problem of denormalized data
22
22
23
-
One of the challenges in working with one-to-many relationships is that standard queries built on joined tables will return denormalized data, which doesn't work well in an Azure Cognitive Search scenario. Consider the following example that joins hotels and rooms.
23
+
One of the challenges in working with one-to-many relationships is that standard queries built on joined tables return denormalized data, which doesn't work well in an Azure Cognitive Search scenario. Consider the following example that joins hotels and rooms.
24
24
25
25
```sql
26
26
SELECT*FROM Hotels$
27
27
INNER JOIN Rooms$
28
28
ON Rooms$.HotelID = Hotels$.HotelID
29
29
```
30
+
30
31
Results from this query return all of the Hotel fields, followed by all Room fields, with preliminary hotel information repeating for each room value.
31
32
32
33

33
34
34
-
35
-
While this query succeeds on the surface (providing all of the data in a flat row set), it fails in delivering the right document structure for the expected search experience. During indexing, Azure Cognitive Search will create one search document for each row ingested. If your search documents looked like the above results, you would have perceived duplicates - seven separate documents for the Twin Dome hotel alone. A query on "hotels in Florida" would return seven results for just the Twin Dome hotel, pushing other relevant hotels deep into the search results.
35
+
While this query succeeds on the surface (providing all of the data in a flat row set), it fails in delivering the right document structure for the expected search experience. During indexing, Azure Cognitive Search creates one search document for each row ingested. If your search documents looked like the above results, you would have perceived duplicates - seven separate documents for the Twin Dome hotel alone. A query on "hotels in Florida" would return seven results for just the Twin Dome hotel, pushing other relevant hotels deep into the search results.
36
36
37
37
To get the expected experience of one document per hotel, you should provide a rowset at the right granularity, but with complete information. This article explains how.
38
38
@@ -42,7 +42,7 @@ To deliver the expected search experience, your data set should consist of one r
42
42
43
43
The solution is to capture the room detail as nested JSON, and then insert the JSON structure into a field in a view, as shown in the second step.
44
44
45
-
1. Assume you have two joined tables, Hotels$ and Rooms$, that contain details for 50 hotels and 750 rooms, and are joined on the HotelID field. Individually, these tables contain 50 hotels and 750 related rooms.
45
+
1. Assume you've two joined tables, Hotels$ and Rooms$, that contain details for 50 hotels and 750 rooms and are joined on the HotelID field. Individually, these tables contain 50 hotels and 750 related rooms.
46
46
47
47
```sql
48
48
CREATE TABLE [dbo].[Hotels$](
@@ -107,7 +107,7 @@ This rowset is now ready for import into Azure Cognitive Search.
107
107
108
108
On the Azure Cognitive Search side, create an index schema that models the one-to-many relationship using nested JSON. The result set you created in the previous section generally corresponds to the index schema provided below (we cut some fields for brevity).
109
109
110
-
The following example is similar to the example in [How to model complex data types](search-howto-complex-data-types.md#create-complex-fields). The *Rooms* structure, which has been the focus of this article, is in the fields collection of an index named *hotels*. This example also shows a complex type for *Address*, which differs from *Rooms* in that it is composed of a fixed set of items, as opposed to the multiple, arbitrary number of items allowed in a collection.
110
+
The following example is similar to the example in [How to model complex data types](search-howto-complex-data-types.md#create-complex-fields). The *Rooms* structure, which has been the focus of this article, is in the fields collection of an index named *hotels*. This example also shows a complex type for *Address*, which differs from *Rooms* in that it's composed of a fixed set of items, as opposed to the multiple, arbitrary number of items allowed in a collection.
111
111
112
112
```json
113
113
{
@@ -117,8 +117,9 @@ The following example is similar to the example in [How to model complex data ty
Given the previous result setand the above index schema, you have all the required components for a successful indexing operation. The flattened data set meets indexing requirements yet preserves detail information. In the Azure Cognitive Search index, search results will fall easily into hotel-based entities, while preserving the context of individual rooms and their attributes.
146
+
Given the previous result setand the above index schema, you've all the required components for a successful indexing operation. The flattened data set meets indexing requirements yet preserves detail information. In the Azure Cognitive Search index, search results will fall easily into hotel-based entities, while preserving the context of individual rooms and their attributes.
147
+
148
+
## Facet behavior on complex type subfields
149
+
150
+
Fields that have a parent, such as the fields under Address and Rooms, are called *subfields*. Although you can assign a "facetable" attribute to a subfield, the count of the facet will always be for the main document.
151
+
152
+
For complex types like Address, where there's just one "Address/City"or"Address/stateProvince"in the document, the facet behavior works as expected. However, in the case of Rooms, where there are multiple subdocuments for each main document, the facet counts can be misleading.
153
+
154
+
As noted in [Model complex types](search-howto-complex-data-types.md): "the document counts returned in the facet results are calculated for the parent document (a hotel), not the subdocuments in a complex collection (rooms). For example, suppose a hotel has 20 rooms of type "suite". Given this facet parameter facet=Rooms/Type, the facet count is one for the hotel, not 20 for the rooms."
Copy file name to clipboardExpand all lines: articles/search/search-indexer-howto-access-private.md
+12-4Lines changed: 12 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -54,7 +54,7 @@ When evaluating shared private links for your scenario, remember these constrain
54
54
55
55
+ An Azure PaaS resource from the following list of supported resource types, configured to run in a virtual network, with a private endpoint created through Azure Private Link.
56
56
57
-
+ You should have a minimum of Contributor permissions on both Cognitive Search and the Azure PaaS resource for which you're creating the shared private link.
57
+
+ You should have a minimum of Contributor permissions on both Azure Cognitive Search and the Azure PaaS resource for which you're creating the shared private link.
58
58
59
59
<aname="group-ids"></a>
60
60
@@ -142,7 +142,9 @@ When you complete these steps, you have a shared private link that's provisioned
142
142
> Preview API versions, either `2020-08-01-preview` or `2021-04-01-preview`, are required for group IDs that are in preview. The following resource types are in preview: `managedInstance`, `mySqlServer`, `sites`.
143
143
> For `managedInstance`, see [create a shared private link for SQL Managed Instance](#create-a-shared-private-link-for-a-sql-managed-instance) for help formulating a fully qualified domain name.
144
144
145
-
Other tools like the portal, Azure PowerShell, or the Azure CLI have built-in mechanisms for account sign-in. If you're using a REST client, such as Postman, you'll need to provide a bearer token that allows your request to go through. Because it's easy and quick, this section uses Azure CLI steps for getting a bearer token. For other approaches, see [Manage with REST](search-manage-rest.md).
145
+
While tools like Azure portal, Azure PowerShell, or the Azure CLI have built-in mechanisms for account sign-in, a REST client like Postman needs to provide a bearer token that allows your request to go through.
146
+
147
+
Because it's easy and quick, this section uses Azure CLI steps for getting a bearer token. For more durable approaches, see [Manage with REST](search-manage-rest.md).
146
148
147
149
1. Open a command line and run `az login` for Azure sign-in.
148
150
@@ -152,6 +154,12 @@ Other tools like the portal, Azure PowerShell, or the Azure CLI have built-in me
152
154
az account show
153
155
```
154
156
157
+
Change the subscription if it's not the right one:
158
+
159
+
```azurecli
160
+
az account set --subscription {{Azure PaaS subscription ID}}
161
+
```
162
+
155
163
1. Create a bearer token, and then copy the entire token (everything between the quotation marks).
156
164
157
165
```azurecli
@@ -168,7 +176,7 @@ Other tools like the portal, Azure PowerShell, or the Azure CLI have built-in me
168
176
169
177
1. Set the content type to JSON.
170
178
171
-
1. Send the request. You should get a list of all shared private link resources that exist for your search service.
179
+
1. Send the request. You should get a list of all shared private link resources that exist for your search service. Make sure there's no existing shared private link for the resource and sub-resource combination.
172
180
173
181
1. Formulate a PUT request to [Create or Update Shared Private Link](/rest/api/searchmanagement/2020-08-01/shared-private-link-resources/create-or-update) for the Azure PaaS resource. Provide a URI and request body similar to the following example:
174
182
@@ -197,7 +205,7 @@ Other tools like the portal, Azure PowerShell, or the Azure CLI have built-in me
197
205
az account get-access-token
198
206
```
199
207
200
-
1. To check the status, rerun the first GET Shared Private Link request to monitor the provisioning state as it transitions from updating to succeeded.
208
+
1.Send the request. To check the status, rerun the first GET Shared Private Link request to monitor the provisioning state as it transitions from updating to succeeded.
0 commit comments