是否可以在Azure搜索索引中填充集合?

时间:2019-08-12 10:11:13

标签: c# azure indexing azure-sql-database azure-cognitive-search

我目前一直在使用Azure搜索,但偶然发现了一个场景,其中有两个表:一个描述一个位置,另一个描述每个位置有多张照片。

我想使用两个索引器来填充相同的索引,其中一个将填充地点的详细信息(名称,坐标等),而另一个将获取照片,运行自定义WebApiSkill来获取某些详细信息从照片中删除,然后将它们添加到索引上的复杂集合中。

问题是,我不知道如何在索引上填充该照片集。我尝试将outputFieldMappings定义为Photos/*/Details,或者仅定义为Photos/Details,但是我仍然遇到相同的错误:

Microsoft.Rest.Azure.CloudException: 'Output field mapping specifies target field 'Photos/*/PhotoURI' that doesn't exist in the index'

考虑到这一点,我想知道是否有可能在Azure搜索中填充这样的复杂集合,如果可以,我将如何去做呢?


表格:

CREATE TABLE Places
(
    Id             bigint         not null  IDENTITY(1,1)  PRIMARY KEY,
    Name           nvarchar(50)   not null,
    Location       nvarchar(50)   not null
);

CREATE TABLE PlacePhotos
(
    PhotoURI  nvarchar(200)  not null  PRIMARY KEY,
    PlaceId   bigint         not null  REFERENCES Places (Id)
);

用于创建索引的类:

public partial class Photo
{
    [IsSearchable]
    public string PhotoURI { get; set; }

    public List<Details> Details { get; set; }
}
public partial class Place
{
    [System.ComponentModel.DataAnnotations.Key]
    public string Id { get; set; }

    [IsSearchable, IsFilterable, IsSortable, IsFacetable]
    public string Name { get; set; } 

    [IsSearchable, IsFilterable]
    public string Location { get; set; }

    [IsSearchable, IsFilterable, IsSortable]
    public List<Photo> Photos { get; set; }

}

索引器(以PlacePhotos表为数据源)

private static void Create_PlacePhotos_Indexer(SearchServiceClient serviceClient)
{
    var indexerDef = new Indexer(
        name: placePhotosIndexer,
        dataSourceName: placePhotosDataSource,
        targetIndexName: index,
        skillsetName: skillset,
        schedule: new IndexingSchedule
        {
            Interval = new TimeSpan(0, 30, 0)
        },
        fieldMappings: new List<FieldMapping>
        {
            new FieldMapping("PlaceId", "Id"),
            new FieldMapping("PhotoURI", "PhotoURI")
        },
        outputFieldMappings: new List<FieldMapping>
        {
            new FieldMapping("/document/Id", "Id"),
            new FieldMapping("/document/PhotoURI", "Photos/*/PhotoURI"),
            new FieldMapping("/document/Details", "Photos/*/Details")
        }
    );
    serviceClient.Indexers.CreateOrUpdate(indexerDef);
}

1 个答案:

答案 0 :(得分:1)

Output field mapping目标字段名称必须是顶级索引字段名称,因此Photos/*/PhotoURI无效,您必须直接定位Photos

要“成形”要映射的Photos值,可以使用ShaperSkill

{
  "@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
  "context": "/document/photos/*",
  "inputs": [
    {
      "name": "PhotoURI",
      "source": "/document/photos/*/PhotoURI"
    },
    {
      "name": "Details",
      "source": "/document/photos/*/Details"
    }
  ],
  "outputs": [
    {
      "name": "output",
      "targetName": "shapedValue"
    }
  ]
}

和输出字段映射

new FieldMapping("/document/photos/*/shapedValue", "Photos")

注意-您可能必须重新布置输出URI和详细信息的技能,因此它们共享共同的context。从上面的代码段看来,每个document都只有1张照片,这与您的索引定义不同。