使用 REST c# 的 Azure 搜索

Azure Search using REST c#

我正在尝试 运行 以下代码:

public class Item
{
    [JsonProperty(PropertyName = "api-key")]
    public string apikey { get; set; }

}

[[some method]]{
            var url = "https://[search service name].search.windows.net/indexes/temp?api-version=2016-09-01"; 

            using (var httpClient = new HttpClient())
            {
                using (var request = new HttpRequestMessage(HttpMethod.Put,url))
                {
                    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));                        
                    var sItem = new Item { apikey = [AzureSearchAdminKey] };
                    var tststring = JsonConvert.SerializeObject(sItem);
                    var body=new  StringContent(tststring, Encoding.UTF8,"application/json" );



                    request.Content =  body;

                    request.Method = HttpMethod.Put;

                    using (HttpResponseMessage response = httpClient.SendAsync(request).Result)
                    {                                                       
                        var stringr = response.Content.ReadAsStringAsync().Result;
                        Console.WriteLine(stringr);
                        Console.ReadLine();
                    }

                }  
            }

}

我收到以下错误: "Error reading JObject from JsonReader. Path '', line 0, position 0."

搜索团队的人可以告诉我我做错了什么吗?

您似乎在尝试修改索引定义,但请求的 body 包含索引定义的 api-key 而不是 JSON。 api-key 需要在请求 headers 中,而不是 body。

您可能会发现使用 Azure Search .NET SDK 比直接调用 REST API 更简单。

api 键应该在 HTTP header 中,索引定义应该在 HTTP body.

下面是一些用于创建 data source, index, and indexer 的示例代码,它从 Azure SQL 数据库中读取并为其行编制索引。

class Program
{
    static void Main(string[] args)
    {
        var searchServiceName = "[search service name]";
        var apiKey = "[api key]";

        var dataSourceName = "[data source name]";
        var indexName = "[index name]";
        var indexerName = "[indexer name]";

        var azureSqlConnectionString = "[Azure SQL connection string]";
        var azureSqlTableName = "[table name]";

        using (var httpClient = new HttpClient())
        {
            var dataSourceDefinition = AzureSqlDatasourceDefinition(azureSqlConnectionString, azureSqlTableName);
            var putDataSourceRequest = PutDataSourceRequest(searchServiceName, apiKey, dataSourceName, dataSourceDefinition);
            Console.WriteLine($"Put data source {putDataSourceRequest.RequestUri}");
            Console.WriteLine();
            var putDataSourceResponse = httpClient.SendAsync(putDataSourceRequest).Result;
            var putDataSourceResponseContent = putDataSourceResponse.Content.ReadAsStringAsync().Result;
            Console.WriteLine(putDataSourceResponseContent);
            Console.WriteLine();

            var indexDefinition = IndexDefinition();
            var putIndexRequest = PutIndexRequest(searchServiceName, apiKey, indexName, indexDefinition);
            Console.WriteLine($"Put index {putIndexRequest.RequestUri}");
            Console.WriteLine();
            var putIndexResponse = httpClient.SendAsync(putIndexRequest).Result;
            var putIndexResponseContent = putIndexResponse.Content.ReadAsStringAsync().Result;
            Console.WriteLine(putIndexResponseContent);
            Console.WriteLine();

            var indexerDefinition = IndexerDefinition(dataSourceName, indexName);
            var putIndexerRequest = PutIndexerRequest(searchServiceName, apiKey, indexerName, indexerDefinition);
            Console.WriteLine($"Put indexer {putIndexerRequest.RequestUri}");
            Console.WriteLine();
            var putIndexerResponse = httpClient.SendAsync(putIndexerRequest).Result;
            var putIndexerResponseContent = putIndexerResponse.Content.ReadAsStringAsync().Result;
            Console.WriteLine(putIndexerResponseContent);
            Console.WriteLine();

            var runIndexerRequest = RunIndexerRequest(searchServiceName, apiKey, indexerName);
            Console.WriteLine($"Run indexer {runIndexerRequest.RequestUri}");
            Console.WriteLine();
            var runIndexerResponse = httpClient.SendAsync(runIndexerRequest).Result;
            Console.WriteLine($"Success: {runIndexerResponse.IsSuccessStatusCode}");
            Console.ReadLine();
        }
    }

    static HttpRequestMessage PutDataSourceRequest(string searchServiceName, string apiKey, string dataSourceName,
        string datasourceDefinition)
    {
        var request = new HttpRequestMessage(HttpMethod.Put,
            $"https://{searchServiceName}.search.windows.net/datasources/{dataSourceName}?api-version=2016-09-01");
        request.Headers.Add("api-key", apiKey);
        var body = new StringContent(datasourceDefinition, Encoding.UTF8, "application/json");
        request.Content = body;
        return request;
    }

    static HttpRequestMessage PutIndexRequest(string searchServiceName, string apiKey, string indexName,
        string indexDefinition)
    {
        var request = new HttpRequestMessage(HttpMethod.Put,
            $"https://{searchServiceName}.search.windows.net/indexes/{indexName}?api-version=2016-09-01");
        request.Headers.Add("api-key", apiKey);
        var body = new StringContent(indexDefinition, Encoding.UTF8, "application/json");
        request.Content = body;
        return request;
    }

    static HttpRequestMessage PutIndexerRequest(string searchServiceName, string apiKey, string indexerName,
        string indexerDefinition)
    {
        var request = new HttpRequestMessage(HttpMethod.Put,
            $"https://{searchServiceName}.search.windows.net/indexers/{indexerName}?api-version=2016-09-01");
        request.Headers.Add("api-key", apiKey);
        var body = new StringContent(indexerDefinition, Encoding.UTF8, "application/json");
        request.Content = body;
        return request;
    }

    static HttpRequestMessage RunIndexerRequest(string searchServiceName, string apiKey, string indexerName)
    {
        var request = new HttpRequestMessage(HttpMethod.Post,
            $"https://{searchServiceName}.search.windows.net/indexers/{indexerName}/run?api-version=2016-09-01");
        request.Headers.Add("api-key", apiKey);
        return request;
    }

    static string AzureSqlDatasourceDefinition(string connectionString, string tableName)
    {
        return @"
{
  ""description"": ""azure sql datasource"",
  ""type"": ""azuresql"",
  ""credentials"": { ""connectionString"": """ + connectionString + @""" },
  ""container"": { ""name"": """ + tableName + @""" },
  ""dataChangeDetectionPolicy"": {
    ""@odata.type"": ""#Microsoft.Azure.Search.HighWaterMarkChangeDetectionPolicy"",
    ""highWaterMarkColumnName"": ""highwatermark""
  },
  ""dataDeletionDetectionPolicy"": {
    ""@odata.type"": ""#Microsoft.Azure.Search.SoftDeleteColumnDeletionDetectionPolicy"",
  ""softDeleteColumnName"": ""deleted"",
  ""softDeleteMarkerValue"": ""true""
  }
}
";
    }

    static string IndexDefinition()
    {
        return @"
{
  ""fields"": [
    {
      ""name"": ""id"",
      ""type"": ""Edm.String"",
      ""key"": true,
      ""searchable"": true,
      ""sortable"": true,
      ""retrievable"": true
    },
    {
      ""name"": ""field1"",
      ""type"": ""Edm.String"",
      ""searchable"": true,
      ""retrievable"": true
    },
    {
      ""name"": ""field3"",
      ""type"": ""Edm.Int32"",
      ""retrievable"": true
    }
  ]
}
";
    }

    static string IndexerDefinition(string dataSourceName, string indexName)
    {
        return @"
{
  ""description"": ""indexer for azure sql datasource"",
  ""dataSourceName"": """ + dataSourceName + @""",
  ""targetIndexName"": """ + indexName + @""",
  ""schedule"": { ""interval"": ""P1D"" }
}
";
    }
}

索引器计划每天 运行 一次。如果数据经常更改,您可以将其设置为 运行 更频繁,但这可能会影响您的搜索吞吐量。

如果您感兴趣,这是 table 定义

CREATE TABLE [dbo].[testtable](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [field1] [nchar](10) NULL,
    [field2] [nchar](10) NULL,
    [field3] [int] NULL,
    [highwatermark] [timestamp] NOT NULL,
    [deleted] [bit] NOT NULL
) ON [PRIMARY]

INSERT INTO [dbo].[testtable] (field1, field2, field3, deleted) VALUES ('abc', 'def', 123, 0)