使用 FieldMapping() 在 Azure 搜索索引器中使用 DataType.Complex

Using DataType.Complex in Azure Search Indexer using FieldMapping()

我正在尝试将嵌套对象从 MongoDB (CosmosDB) 映射到 Azure 搜索索引器。

首先,这是我存储在 MongoDB 中的内容。

{
    "_id" : {
        "$binary" : "eHemgNj2FkWlqECKkGKnJA==",
        "$type" : "03"
    },
    "UpdatedBy" : {
        "_id" : {
            "$binary" : "0wtu6BgDm0GrTbffr1EmhQ==",
            "$type" : "03"
        },
        "Email" : "canuserview@gmail.com"
    },
    "Status" : "New",
    "Name" : "123",
    "CustomerName" : ""
}

然后,我有一个 c# 程序使用 Microsoft.Azure.Search.Models nuget 包以编程方式创建索引。

private async Task StartIndexAsync(bool resetIndexer = true)
{
    await CreateIndexAsync(new[]{
        new Field(nameof(ProjectSearchModel.Id),              DataType.String)     { IsKey = true,  IsSearchable = false, IsFilterable = false, IsSortable = false, IsFacetable = false, IsRetrievable = true},
        new Field(nameof(ProjectSearchModel.Name),            DataType.String)     { IsKey = false,  IsSearchable = true, IsFilterable = true, IsSortable = true, IsFacetable = false, IsRetrievable = true},
        new Field(nameof(ProjectSearchModel.CustomerName),    DataType.String)     { IsKey = false,  IsSearchable = true, IsFilterable = true, IsSortable = true, IsFacetable = false, IsRetrievable = true},
        Field.NewComplex(nameof(ProjectSearchModel.UpdatedBy), false, new [] {
            new Field(nameof(ProjectSearchModel.UpdatedBy.Id),     DataType.String)     { IsKey = false,  IsSearchable = false, IsFilterable = false, IsSortable = false, IsFacetable = false, IsRetrievable = true},
            new Field(nameof(ProjectSearchModel.UpdatedBy.Email),  DataType.String)     { IsKey = false,  IsSearchable = true, IsFilterable = true, IsSortable = true, IsFacetable = false, IsRetrievable = true}
        })
        },
    new[] {
        nameof(ProjectSearchModel.Name),
        nameof(ProjectSearchModel.Number),
        nameof(ProjectSearchModel.CustomerName),
        $"{nameof(ProjectSearchModel.UpdatedBy)}/{nameof(ProjectSearchModel.UpdatedBy.Email)}"
    });

    await CreateDatasourceAsync();
    await StartIndexerAsync(resetIndexer);
}

然后,对于索引器,我定义了一些FieldMappings,因为我想将MongoDB中的_id映射到索引器中的Id字段。

public async Task CreateIndexerAsync(string indexerName, string datasourceName, string indexName)
{
    _logger.LogInformation("{0}", "Creating Indexer and syncing data...\n");

    var indexer =
        new Indexer()
        {
            Name = indexerName,
            Description = "Data indexer",
            DataSourceName = datasourceName,
            TargetIndexName = indexName,
            FieldMappings = new List<FieldMapping> { new FieldMapping() { SourceFieldName = "doc_id", TargetFieldName = "Id" } }
        };

    try
    {
        await _searchClient.Indexers.CreateOrUpdateAsync(indexer);
    }
    catch (Exception ex)
    {
        _logger.LogError("Error creating and running indexer: {0}", ex.Message);
        return;
    }

    await StartCreation(indexerName);
}             

现在,MongoDB 中的 _id 已正确映射到上述代码中 Indexer 中的 Id 字段。

{
    "@odata.context": "myprojectendpoint/indexes('myproject-index-dev')/$metadata#docs(*)",
    "value": [
        {
            "@search.score": 1,
            "Id": "30dbf04d-cbc7-4597-8d48-209f3a320cf8",
            "Name": "friday soon",
            "CustomerName": "Kyle Ahn",
            "UpdatedBy": {
                "Id": null,
                "Email": "kyle.ahn@onthestep.ca"
            }
        }
    ]
}

我想对 UpdatedBy 字段中的 Id 子字段执行相同的操作。所以,我想将 MongoDB 中的 UpdatedBy._id 映射到索引中的 UpdatedBy/Id。

有办法实现吗?

非常感谢大家!

A​​zure 搜索索引器不支持此功能。添加字段映射时,您的目标应该是顶级索引字段。这意味着,您可以将一个复杂对象从您的数据源作为一个整体映射到索引中的一个复杂字段 - 但您不能将一个子字段从源中的一个复杂对象映射到一个复杂字段的“子”你的指数。

field mappings document 中的第 2 点说明了这一点,但我会对其进行更新以使其更清楚。

作为解决方法,您可以尝试修改“UpdatedBy”属性 以拥有与索引定义一致的子字段;或者您可以尝试使用 SDK 直接修改子字段,使用类似以下内容(我假设您的索引数据模型的名称)

IndexAction.MergeOrUpload(
    new Customer()
    {
        Id = "....",
        UpdatedBy = new 
        {
            Id = "..."
        }
    }
)

这会将您的 MongoDb 中缺少的 ID 属性“合并”(添加)到您的搜索索引中 - 请注意,这只有效,因为您的“UpdatedBy”复杂字段不是集合。