更新documentDb更改的搜索索引

时间:2018-02-16 15:03:45

标签: azure azure-cosmosdb azure-search

我希望Azure-Search-Index与我存储在Azure-DocumentDB中的文档保持同步。索引器可以完成这项工作,但这不适合我,因为必须更新Search-Index以及从DocumentDB结构到Index-Scheme的映射非常复杂。

我可以使用DocumentDB触发器来执行此操作吗?

(执行http调用 - 可能是Azure函数 - 获取更改的DocumentDB文档并调用Azure搜索服务来更新搜索索引)

1 个答案:

答案 0 :(得分:1)

您可以挂钩Cosmos DB Trigger以侦听集合中的更改,在Azure函数中处理这些更改并将其发送到Azure搜索。

例如,下一个函数侦听文档,对年龄进行一些简单计算并将批处理发送到搜索:

示例文件:

{
    "name": "john",
    "born": "1983-05-07",
    "id": "some-id"
}

run.csx

#r "Microsoft.Azure.Documents.Client"
using System;
using System.Configuration;
using System.Collections.Generic;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Search;

private static string searchServiceName = ConfigurationManager.AppSettings["SearchServiceName"];
private static string searchServiceKey = ConfigurationManager.AppSettings["SearchServiceKey"];
private static SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(searchServiceKey));
private static ISearchIndexClient indexClient = serviceClient.Indexes.GetClient(ConfigurationManager.AppSettings["SearchServiceIndexName"]);

public class IndexItem {
    public string id {get;set;}
    public string name {get;set;}
    public int age {get;set;}
}

public static void Run(IReadOnlyList<Document> documents, TraceWriter log)
{
    log.Verbose("Documents modified " + documents.Count);

    if (documents != null && documents.Count > 0)
    {
        var batch = Microsoft.Azure.Search.Models.IndexBatch.MergeOrUpload(documents.Select(
            // Do any transformation needed
            doc => new IndexItem(){
                id = doc.GetPropertyValue<string>("id"),
                name = doc.GetPropertyValue<string>("name"),
                age = CalculateAge(doc.GetPropertyValue<string>("born"))
            }
        ));

        try
        {
            indexClient.Documents.Index(batch);
        }
        catch (IndexBatchException e)
        {
            // Sometimes when your Search service is under load, indexing will fail for some of the documents in
            // the batch. Depending on your application, you can take compensating actions like delaying and
            // retrying. For this simple demo, we just log the failed document keys and continue.            
            log.Error(
                string.Format("Failed to index some of the documents: {0}",
                String.Join(", ", e.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key))));
            log.Error(e.Message);
        }
    }
}

private static int CalculateAge(string born){
    DateTime bday = DateTime.ParseExact(born,"yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
    DateTime now = DateTime.Today;
    var age = now.Year - bday.Year;
    if (bday > now.AddYears(-age)) age--;
    return age;
}

您需要添加Azure Search Nuget包,为此添加project.json文件到您的Azure功能:

{
  "frameworks": {
    "net46":{
      "dependencies": {
        "Microsoft.Azure.Search": "3.0.5"
      }
    }
   }
}