Skip to content

Commit 6d77116

Browse files
authored
Merge pull request #180336 from HeidiSteen/heidist-nov1
[azure search] GH issue, complex fields is missing a C# example
2 parents 2c91e48 + d1b585d commit 6d77116

File tree

3 files changed

+95
-13
lines changed

3 files changed

+95
-13
lines changed

articles/search/index-sql-relational-data.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ This rowset is now ready for import into Azure Cognitive Search.
107107

108108
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).
109109

110-
The following example is similar to the example in [How to model complex data types](search-howto-complex-data-types.md#creating-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 is composed of a fixed set of items, as opposed to the multiple, arbitrary number of items allowed in a collection.
111111

112112
```json
113113
{

articles/search/search-how-to-create-search-index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ When you're ready to create the index, there are several ways to move forward. W
8484

8585
During development, plan on frequent rebuilds. Because physical structures are created in the service, [dropping and re-creating indexes](search-howto-reindex.md) is necessary for many modifications. You might consider working with a subset of your data to make rebuilds go faster.
8686

87-
### [**Azure portal**](#tab/indexer-portal)
87+
### [**Azure portal**](#tab/index-portal)
8888

8989
Index design through the portal enforces requirements and schema rules for specific data types, such as disallowing full text search capabilities on numeric fields. In the portal, there are two options for creating a search index:
9090

@@ -100,7 +100,7 @@ The following screenshot shows where you can find **Add index** and **Import dat
100100
> [!Tip]
101101
> After creating an index in the portal, you can copy the JSON representation and add it to your application code.
102102
103-
### [**REST**](#tab/kstore-rest)
103+
### [**REST**](#tab/index-rest)
104104

105105
[**Create Index (REST)**](/rest/api/searchservice/create-index) is used to create an index. Both Postman and Visual Studio Code (with an extension for Azure Cognitive Search) can function as a search index client. Using either tool, you can connect to your search service and send requests:
106106

@@ -135,7 +135,7 @@ POST https://[servicename].search.windows.net/indexes?api-version=[api-version]
135135
}
136136
```
137137

138-
### [**.NET SDK**](#tab/kstore-dotnet)
138+
### [**.NET SDK**](#tab/index-dotnet)
139139

140140
The Azure SDK for .NET has [**SearchIndexClient**](/dotnet/api/azure.search.documents.indexes.searchindexclient) with methods for creating and updating indexes.
141141

@@ -169,7 +169,7 @@ await indexClient.CreateIndexAsync(index);
169169

170170
For more examples, see[azure-search-dotnet-samples/quickstart/v11/](https://github.com/Azure-Samples/azure-search-dotnet-samples/tree/master/quickstart/v11).
171171

172-
### [**Other SDKs**](#tab/other-sdks)
172+
### [**Other SDKs**](#tab/index-other-sdks)
173173

174174
For Cognitive Search, the Azure SDKs implement generally available features. As such, you can use any of the SDKs to create a search index. All of them provide a **SearchIndexClient** that has methods for creating and updating indexes.
175175

articles/search/search-howto-complex-data-types.md

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: How to model complex data types
2+
title: Model complex data types
33
titleSuffix: Azure Cognitive Search
44
description: Nested or hierarchical data structures can be modeled in an Azure Cognitive Search index using ComplexType and Collections data types.
55

@@ -8,11 +8,11 @@ author: brjohnstmsft
88
ms.author: brjohnst
99
tags: complex data types; compound data types; aggregate data types
1010
ms.service: cognitive-search
11-
ms.topic: conceptual
12-
ms.date: 04/02/2021
11+
ms.topic: how-to
12+
ms.date: 11/17/2021
1313
---
1414

15-
# How to model complex data types in Azure Cognitive Search
15+
# Model complex data types in Azure Cognitive Search
1616

1717
External datasets used to populate an Azure Cognitive Search index can come in many shapes. Sometimes they include hierarchical or nested substructures. Examples might include multiple addresses for a single customer, multiple colors and sizes for a single SKU, multiple authors of a single book, and so on. In modeling terms, you might see these structures referred to as *complex*, *compound*, *composite*, or *aggregate* data types. The term Azure Cognitive Search uses for this concept is **complex type**. In Azure Cognitive Search, complex types are modeled using **complex fields**. A complex field is a field that contains children (sub-fields) which can be of any data type, including other complex types. This works in a similar way as structured data types in a programming language.
1818

@@ -65,10 +65,26 @@ During indexing, you can have a maximum of 3000 elements across all complex coll
6565

6666
This limit applies only to complex collections, and not complex types (like Address) or string collections (like Tags).
6767

68-
## Creating complex fields
68+
## Create complex fields
6969

7070
As with any index definition, you can use the portal, [REST API](/rest/api/searchservice/create-index), or [.NET SDK](/dotnet/api/azure.search.documents.indexes.models.searchindex) to create a schema that includes complex types.
7171

72+
### [**Azure portal**](#tab/complex-type-portal)
73+
74+
1. On the search service **Overview** page, select the **Indexes** tab.
75+
76+
1. Open an existing index or create a new index.
77+
78+
1. Select the **Fields** tab, and then select **Add field**. An empty field is added. If you're working with an existing fields collection, scroll down to set up the field.
79+
80+
1. Give the field a name and set the type to either `Edm.ComplexType` or `Collection(Edm.ComplexType)`.
81+
82+
1. Select the ellipses on the far right, and then select either **Add field** or **Add subfield**, and then assign attributes.
83+
84+
### [**REST**](#tab/complex-type-rest)
85+
86+
Use [Create Index (REST API)](/rest/api/searchservice/create-index) to define a schema.
87+
7288
The following example shows a JSON index schema with simple fields, collections, and complex types. Notice that within a complex type, each sub-field has a type and may have attributes, just as top-level fields do. The schema corresponds to the example data above. `Address` is a complex field that isn't a collection (a hotel has one address). `Rooms` is a complex collection field (a hotel has many rooms).
7389

7490
```json
@@ -96,7 +112,73 @@ The following example shows a JSON index schema with simple fields, collections,
96112
}
97113
```
98114

99-
## Updating complex fields
115+
### [**.NET SDK**](#tab/complex-type-dotnet)
116+
117+
Use the [Search Index class](/dotnet/api/azure.search.documents.indexes.models.searchindex) to define the index schema.
118+
119+
The following snippets are from [search-dotnet-getting-started/DotNetHowTo](https://github.com/Azure-Samples/search-dotnet-getting-started/tree/master/DotNetHowTo/DotNetHowTo).
120+
121+
In the Hotels sample index, `Address` is a complex field that isn't a collection (a hotel has one address). `Rooms` is a complex collection field (a hotel has many rooms). Both [Address](https://github.com/Azure-Samples/search-dotnet-getting-started/blob/master/DotNetHowTo/DotNetHowTo/Address.cs) and [Room](https://github.com/Azure-Samples/search-dotnet-getting-started/blob/master/DotNetHowTo/DotNetHowTo/Room.cs) are defined as classes.
122+
123+
```csharp
124+
using Azure.Search.Documents.Indexes;
125+
126+
namespace AzureSearch.SDKHowTo
127+
{
128+
public partial class Address
129+
{
130+
[SearchableField(IsFilterable = true)]
131+
public string StreetAddress { get; set; }
132+
133+
[SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
134+
public string City { get; set; }
135+
136+
[SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
137+
public string StateProvince { get; set; }
138+
139+
[SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
140+
public string PostalCode { get; set; }
141+
142+
[SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
143+
public string Country { get; set; }
144+
}
145+
}
146+
```
147+
148+
In [Hotel.cs](https://github.com/Azure-Samples/search-dotnet-getting-started/blob/master/DotNetHowTo/DotNetHowTo/Hotel.cs), both Address and Room are members of Hotel.
149+
150+
```csharp
151+
using System;
152+
using Microsoft.Spatial;
153+
using System.Text.Json.Serialization;
154+
using Azure.Search.Documents.Indexes;
155+
using Azure.Search.Documents.Indexes.Models;
156+
157+
namespace AzureSearch.SDKHowTo
158+
{
159+
public partial class Hotel
160+
{
161+
[SimpleField(IsKey = true, IsFilterable = true)]
162+
public string HotelId { get; set; }
163+
164+
[SearchableField(IsSortable = true)]
165+
public string HotelName { get; set; }
166+
167+
// Removed multiple fields for brevity
168+
169+
// Address is declared as type Address
170+
[SearchableField]
171+
public Address Address { get; set; }
172+
173+
// Room array is declared as type Room
174+
public Room[] Rooms { get; set; }
175+
}
176+
}
177+
```
178+
179+
---
180+
181+
## Update complex fields
100182

101183
All of the [reindexing rules](search-howto-reindex.md) that apply to fields in general still apply to complex fields. Restating a few of the main rules here, adding a field to a complex type doesn't require an index rebuild, but most modifications do.
102184

@@ -110,7 +192,7 @@ Notice that within a complex type, each sub-field has a type and may have attrib
110192

111193
Updating existing documents in an index with the `upload` action works the same way for complex and simple fields -- all fields are replaced. However, `merge` (or `mergeOrUpload` when applied to an existing document) doesn't work the same across all fields. Specifically, `merge` doesn't support merging elements within a collection. This limitation exists for collections of primitive types and complex collections. To update a collection, you'll need to retrieve the full collection value, make changes, and then include the new collection in the Index API request.
112194

113-
## Searching complex fields
195+
## Search complex fields
114196

115197
Free-form search expressions work as expected with complex types. If any searchable field or sub-field anywhere in a document matches, then the document itself is a match.
116198

@@ -120,7 +202,7 @@ Queries get more nuanced when you have multiple terms and operators, and some te
120202
121203
Queries like this are *uncorrelated* for full-text search, unlike filters. In filters, queries over sub-fields of a complex collection are correlated using range variables in [`any` or `all`](search-query-odata-collection-operators.md). The Lucene query above returns documents containing both "Portland, Maine" and "Portland, Oregon", along with other cities in Oregon. This happens because each clause applies to all values of its field in the entire document, so there's no concept of a "current sub-document". For more information on this, see [Understanding OData collection filters in Azure Cognitive Search](search-query-understand-collection-filters.md).
122204

123-
## Selecting complex fields
205+
## Select complex fields
124206

125207
The `$select` parameter is used to choose which fields are returned in search results. To use this parameter to select specific sub-fields of a complex field, include the parent field and sub-field separated by a slash (`/`).
126208

0 commit comments

Comments
 (0)