|
| 1 | +--- |
| 2 | +title: Create a search index |
| 3 | +titleSuffix: Azure Cognitive Search |
| 4 | +description: Create a search index using the Azure portal, REST APIs, or an Azure SDK. |
| 5 | + |
| 6 | +manager: nitinme |
| 7 | +author: HeidiSteen |
| 8 | +ms.author: heidist |
| 9 | + |
| 10 | +ms.service: cognitive-search |
| 11 | +ms.topic: how-to |
| 12 | +ms.date: 11/08/2021 |
| 13 | +--- |
| 14 | + |
| 15 | +# Create a search index in Azure Cognitive Search |
| 16 | + |
| 17 | +Query requests in Azure Cognitive Search target searchable text in a search index. In this article, learn the steps for defining and publishing a search index using any of the modalities supported by Azure Cognitive Search. |
| 18 | + |
| 19 | +Unless you are using an [indexer](search-howto-create-indexers.md), creating an index and populating an index are separate tasks. For non-indexer scenarios, your next step after index creation will be [data import](search-what-is-data-import.md). For more background, see [Search indexes in Azure Cognitive Search](search-what-is-an-index.md). |
| 20 | + |
| 21 | +## Prerequisites |
| 22 | + |
| 23 | +Write permissions on the search service are required for creating and loading indexes. Most operations will require that you provide an [admin API key](search-security-api-keys.md) on the create index request. Alternatively, if you're participating in the Azure Active Directory [role-based access control public preview](search-security-rbac.md), you can issue your request as a member of the Search Contributor role. |
| 24 | + |
| 25 | +Index creation is largely a schema definition exercise. Before creating one, you should have: |
| 26 | + |
| 27 | ++ A clear idea of which fields you want to make searchable, retrievable, filterable, facetable, and sortable in your index. |
| 28 | + |
| 29 | + The [field attribute assignments](search-what-is-an-index.md#index-attributes) will determine its physical storage structure on the search service. During design and development, start with sample data so that you can drop and rebuild the index easily as you finalize field attribution. |
| 30 | + |
| 31 | ++ A source field that uniquely identifies each row, record, or item in the source data. If you're indexing from Blob Storage, the storage path is often used as the document key. |
| 32 | + |
| 33 | + Every index requires one field that serves as the *document key* (sometimes referred to as the "document ID"), and this key is mapped to a source field containing a unique identifier. The ability to uniquely identify specific search documents is required for retrieving a specific document in the search index, and for selective data processing by pulling the right one from source data. |
| 34 | + |
| 35 | ++ Index location. Moving an existing index to a different search service is not supported out-of-the-box. Revisit application requirements and make sure the existing search service, its capacity and location, are sufficient for your needs. |
| 36 | + |
| 37 | +Finally, all service tiers have [index limits](search-limits-quotas-capacity.md#index-limits) on the number of objects that you can create. For example, if you are experimenting on the Free tier, you can only have 3 indexes at any given time. Within the index itself, there are limits on the number of complex fields and collections. |
| 38 | + |
| 39 | +## Allowed updates |
| 40 | + |
| 41 | +[Create Index](/rest/api/searchservice/create-index) is an operation that creates physical data structures (files and inverted indexes) on your search service. Your ability to effect changes using [Update Index](/rest/api/searchservice/update-index) is contingent upon whether the modification invalidates those physical structures. Most field attributes can't be changed once the field is created in your index. |
| 42 | + |
| 43 | +To minimize churn in the design process, the following table describes which elements are fixed and flexible in the schema. Changing a fixed element requires an index rebuild, whereas flexible elements can be changed at any time without impacting the physical implementation. |
| 44 | + |
| 45 | +| Element | Allowed update | |
| 46 | +|---------|----------------| |
| 47 | +| Name | No | |
| 48 | +| Key | No | |
| 49 | +| Field names and types | No | |
| 50 | +| Field attributes (searchable, filterable, facetable, sortable) | No | |
| 51 | +| Field attribute (retrievable) | Yes | |
| 52 | +| [Analyzer](search-analyzers.md) | You can add and modify custom analyzers in the index. Regarding analyzer assignments on string fields, you can only modify "searchAnalyzer". All other assignments and modifications require a rebuild. | |
| 53 | +| [Scoring profiles](index-add-scoring-profiles.md) | Yes | |
| 54 | +| [Suggesters](index-add-suggesters.md) | No | |
| 55 | +| [cross-origin remote scripting (CORS)](search-what-is-an-index.md#corsoptions) | Yes | |
| 56 | +| [Encryption](search-security-manage-encryption-keys.md) | Yes | |
| 57 | + |
| 58 | +> [!NOTE] |
| 59 | +> [Synonym maps](search-synonyms.md) are not part of an index definition. Modifications to a synonym map have no impact on the physical search index. |
| 60 | +
|
| 61 | +## Schema checklist |
| 62 | + |
| 63 | +Use this checklist to help drive the design decisions for your search index. |
| 64 | + |
| 65 | +1. Review [naming conventions](/rest/api/searchservice/naming-rules) so that index and field names conform to the naming rules. |
| 66 | + |
| 67 | +1. Review [supported data types](/rest/api/searchservice/supported-data-types). The data type will impact how the field is used. For example, numeric content is filterable but not full text searchable. |
| 68 | + |
| 69 | +1. Identify one field in the data source that contains unique values, allowing it to function as the key field in your index. |
| 70 | + |
| 71 | +1. Identify the fields in your data source that can contribute searchable content in the index. Searchable content are short or long strings that are queried using the full text search engine. If the content is verbose (small phrases or bigger chunks), experiment with different analyzers to see how the text is tokenized. |
| 72 | + |
| 73 | +1. Identify which source fields can be used as filters. Numeric content and short text fields, particularly those with repeating values, are good choices. When working with filters, remember: |
| 74 | + |
| 75 | + + Filterable fields can optionally be used in faceted navigation. |
| 76 | + |
| 77 | + + Filterable fields are returned in arbitrary order, so consider making them sortable as well. |
| 78 | + |
| 79 | +## Formulate a request |
| 80 | + |
| 81 | +When you're ready to create the index, there are several ways to move forward. We recommend the Azure portal or REST APIs for early development and proof-of-concept testing. |
| 82 | + |
| 83 | +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. |
| 84 | + |
| 85 | +### [**Azure portal**](#tab/indexer-portal) |
| 86 | + |
| 87 | +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: |
| 88 | + |
| 89 | ++ **Add index** is an embedded editor for specifying an index schema |
| 90 | ++ [**Import data**](search-import-data-portal.md) is a wizard |
| 91 | + |
| 92 | +The wizard packs in additional operations by also creating an indexer, data source, and loading data. If this is more than what you want, you should just use **Add index** or another approach. |
| 93 | + |
| 94 | +The following screenshot shows where you can find **Add index** and **Import data** on the command bar. After an index is created, you can find it again in the **Indexes** tab. |
| 95 | + |
| 96 | + :::image type="content" source="media/search-what-is-an-index/add-index.png" alt-text="Add index command" border="true"::: |
| 97 | + |
| 98 | +> [!Tip] |
| 99 | +> After creating an index in the portal, you can copy the JSON representation and add it to your application code. |
| 100 | +
|
| 101 | +### [**REST**](#tab/kstore-rest) |
| 102 | + |
| 103 | +[**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: |
| 104 | + |
| 105 | ++ [Create a search index using REST and Postman](search-get-started-rest.md) |
| 106 | ++ [Get started with Visual Studio Code and Azure Cognitive Search](search-get-started-vs-code.md) |
| 107 | + |
| 108 | +The REST API provides defaults for field attribution. For example, all Edm.String fields are searchable by default. Attributes are shown in full below for illustrative purposes, but you can omit attribution in cases where the default values apply. |
| 109 | + |
| 110 | +Refer to the [Index operations (REST)](/rest/api/searchservice/index-operations) for help with formulating index requests. |
| 111 | + |
| 112 | +```json |
| 113 | +POST https://[servicename].search.windows.net/indexes?api-version=[api-version] |
| 114 | +{ |
| 115 | + "name": "hotels", |
| 116 | + "fields": [ |
| 117 | + { "name": "HotelId", "type": "Edm.String", "key": true, "retrievable": true, "searchable": true, "filterable": true }, |
| 118 | + { "name": "HotelName", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": false, "sortable": true, "facetable": false }, |
| 119 | + { "name": "Description", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzer": "en.microsoft" }, |
| 120 | + { "name": "Description_fr", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzer": "fr.microsoft" }, |
| 121 | + { "name": "Address", "type": "Edm.ComplexType", |
| 122 | + "fields": [ |
| 123 | + { "name": "StreetAddress", "type": "Edm.String", "retrievable": true, "filterable": false, "sortable": false, "facetable": false, "searchable": true }, |
| 124 | + { "name": "City", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": true, "sortable": true, "facetable": true }, |
| 125 | + { "name": "StateProvince", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": true, "sortable": true, "facetable": true } |
| 126 | + ] |
| 127 | + } |
| 128 | + ], |
| 129 | + "suggesters": [ ], |
| 130 | + "scoringProfiles": [ ], |
| 131 | + "analyzers":(optional)[ ... ] |
| 132 | + } |
| 133 | +} |
| 134 | +``` |
| 135 | + |
| 136 | +### [**.NET SDK**](#tab/kstore-dotnet) |
| 137 | + |
| 138 | +The Azure SDK for .NET has [**SearchIndexClient**](/dotnet/api/azure.search.documents.indexes.searchindexclient) with methods for creating and updating indexes. |
| 139 | + |
| 140 | +```csharp |
| 141 | +// Create the index |
| 142 | +string indexName = "hotels"; |
| 143 | +SearchIndex index = new SearchIndex(indexName) |
| 144 | +{ |
| 145 | + Fields = |
| 146 | + { |
| 147 | + new SimpleField("hotelId", SearchFieldDataType.String) { IsKey = true, IsFilterable = true, IsSortable = true }, |
| 148 | + new SearchableField("hotelName") { IsFilterable = true, IsSortable = true }, |
| 149 | + new SearchableField("description") { AnalyzerName = LexicalAnalyzerName.EnLucene }, |
| 150 | + new SearchableField("descriptionFr") { AnalyzerName = LexicalAnalyzerName.FrLucene } |
| 151 | + new ComplexField("address") |
| 152 | + { |
| 153 | + Fields = |
| 154 | + { |
| 155 | + new SearchableField("streetAddress"), |
| 156 | + new SearchableField("city") { IsFilterable = true, IsSortable = true, IsFacetable = true }, |
| 157 | + new SearchableField("stateProvince") { IsFilterable = true, IsSortable = true, IsFacetable = true }, |
| 158 | + new SearchableField("country") { SynonymMapNames = new[] { synonymMapName }, IsFilterable = true, IsSortable = true, IsFacetable = true }, |
| 159 | + new SearchableField("postalCode") { IsFilterable = true, IsSortable = true, IsFacetable = true } |
| 160 | + } |
| 161 | + } |
| 162 | + } |
| 163 | +}; |
| 164 | + |
| 165 | +await indexClient.CreateIndexAsync(index); |
| 166 | +``` |
| 167 | + |
| 168 | +For more examples, see[azure-search-dotnet-samples/quickstart/v11/](https://github.com/Azure-Samples/azure-search-dotnet-samples/tree/master/quickstart/v11). |
| 169 | + |
| 170 | +### [**Other SDKs**](#tab/other-sdks) |
| 171 | + |
| 172 | +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. |
| 173 | + |
| 174 | +| Azure SDK | Client | Examples | |
| 175 | +|-----------|--------|----------| |
| 176 | +| Java | [SearchIndexClient](/java/api/com.azure.search.documents.indexes.searchindexclient) | [CreateIndexExample.java](https://github.com/Azure/azure-sdk-for-java/blob/azure-search-documents_11.1.3/sdk/search/azure-search-documents/src/samples/java/com/azure/search/documents/indexes/CreateIndexExample.java) | |
| 177 | +| JavaScript | [SearchIndexClient](/javascript/api/@azure/search-documents/searchindexclient) | [Indexes](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/search/search-documents/samples/v11/javascript) | |
| 178 | +| Python | [SearchIndexClient](/python/api/azure-search-documents/azure.search.documents.indexes.searchindexclient) | [sample_index_crud_operations.py](https://github.com/Azure/azure-sdk-for-python/blob/7cd31ac01fed9c790cec71de438af9c45cb45821/sdk/search/azure-search-documents/samples/sample_index_crud_operations.py) | |
| 179 | + |
| 180 | +--- |
| 181 | + |
| 182 | +## Next steps |
| 183 | + |
| 184 | +Use the following links to become familiar with loading an index with data. |
| 185 | + |
| 186 | ++ [Data import overview](search-what-is-data-import.md) |
| 187 | + |
| 188 | ++ [Add, Update or Delete Documents (REST)](/rest/api/searchservice/addupdate-or-delete-documents) |
0 commit comments