最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - One Index, Two Indexers, Populate Array - Stack Overflow

programmeradmin2浏览0评论

My index looks like this:

public class Content
{
    [SimpleField(IsFilterable = true, IsKey = true)]
    public required string Id { get; set; }

    [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
    public required string ContentType { get; set; }

    [SearchableField(IsSortable = true, AnalyzerName = LexicalAnalyzerName.Values.StandardLucene)]
    public required string Name { get; set; }

    [SearchableField(IsSortable = true, AnalyzerName = LexicalAnalyzerName.Values.StandardLucene)]
    public string? Description { get; set; }

    [SimpleField(IsFilterable = true, IsFacetable = true)]
    public ICollection<string> Subscriptions { get; set; } = [];
}

The first indexer is properly working and populates all of the properties except Subscriptions from a content SQL database.

The second indexer is not working as I would like it to. Our subscription data is in a separate database and links via ContentId. So, the query I'm using on the indexer is:

SELECT SC.ContentId AS ContentId
    , S.SubscriptionName AS SubscriptionName
    , SC.ModifyDate AS ModifyDate
FROM dbo.SubscriptionContent SC
INNER JOIN dbo.Subscription S ON S.SubscriptionId = SC.SubscriptionId

My FieldMappings on this index is:

[new FieldMapping("ContentId") { TargetFieldName = nameof(Content.Id) }]

I've attempted to use a Skillset to group by the ContentId and put all of the SubscriptionNames in the Subscriptions Collection(Edm.String).

var shaperInputs = new List<InputFieldMappingEntry>
{
    new InputFieldMappingEntry("inputs")
    {
        Source = "/document/SubscriptionName"
    },
    new InputFieldMappingEntry("groupBy")
    {
        Source = "/document/ContentId"
    }
};

var shaperOutputs = new List<OutputFieldMappingEntry>
{
    new OutputFieldMappingEntry("output")
    {
        TargetName = "groupedSubscriptionNames"
    }
};

var skillset = new SearchIndexerSkillset("content-index-subscription-skillset", new List<SearchIndexerSkill>
{
    new ShaperSkill(shaperInputs, shaperOutputs)
    {
        Name = "groupSubscriptionNames",
        Description = "Group SubscriptionNames by ContentId",
        Context = "/document"
    }
});

Then I add OutputFieldMappings of:

[new FieldMapping("/document/groupedSubscriptionOptionNames") { TargetFieldName = nameof(Content.Subscriptions) }]

None of the Subscriptions get populated. What am I doing wrong?

My index looks like this:

public class Content
{
    [SimpleField(IsFilterable = true, IsKey = true)]
    public required string Id { get; set; }

    [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
    public required string ContentType { get; set; }

    [SearchableField(IsSortable = true, AnalyzerName = LexicalAnalyzerName.Values.StandardLucene)]
    public required string Name { get; set; }

    [SearchableField(IsSortable = true, AnalyzerName = LexicalAnalyzerName.Values.StandardLucene)]
    public string? Description { get; set; }

    [SimpleField(IsFilterable = true, IsFacetable = true)]
    public ICollection<string> Subscriptions { get; set; } = [];
}

The first indexer is properly working and populates all of the properties except Subscriptions from a content SQL database.

The second indexer is not working as I would like it to. Our subscription data is in a separate database and links via ContentId. So, the query I'm using on the indexer is:

SELECT SC.ContentId AS ContentId
    , S.SubscriptionName AS SubscriptionName
    , SC.ModifyDate AS ModifyDate
FROM dbo.SubscriptionContent SC
INNER JOIN dbo.Subscription S ON S.SubscriptionId = SC.SubscriptionId

My FieldMappings on this index is:

[new FieldMapping("ContentId") { TargetFieldName = nameof(Content.Id) }]

I've attempted to use a Skillset to group by the ContentId and put all of the SubscriptionNames in the Subscriptions Collection(Edm.String).

var shaperInputs = new List<InputFieldMappingEntry>
{
    new InputFieldMappingEntry("inputs")
    {
        Source = "/document/SubscriptionName"
    },
    new InputFieldMappingEntry("groupBy")
    {
        Source = "/document/ContentId"
    }
};

var shaperOutputs = new List<OutputFieldMappingEntry>
{
    new OutputFieldMappingEntry("output")
    {
        TargetName = "groupedSubscriptionNames"
    }
};

var skillset = new SearchIndexerSkillset("content-index-subscription-skillset", new List<SearchIndexerSkill>
{
    new ShaperSkill(shaperInputs, shaperOutputs)
    {
        Name = "groupSubscriptionNames",
        Description = "Group SubscriptionNames by ContentId",
        Context = "/document"
    }
});

Then I add OutputFieldMappings of:

[new FieldMapping("/document/groupedSubscriptionOptionNames") { TargetFieldName = nameof(Content.Subscriptions) }]

None of the Subscriptions get populated. What am I doing wrong?

Share Improve this question edited 2 days ago ScubaSteve asked Feb 7 at 21:07 ScubaSteveScubaSteve 8,27011 gold badges61 silver badges74 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I was able to figure out a solution for this. Instead of using any sort of Skillset, I utilized the jsonArrayToStringCollectionFunction mapping function in the FieldMapping. First I needed to alter my query to get the SubscriptionNames into a string representing an array of strings. Ex: "['Basic', 'Pro', 'Ultimate']".

So, my query became:

SELECT SC.ContentId AS ContentId
  ,'[' + STRING_AGG('"' + S.SubscriptionName + '"', ',') + ']' AS SubscriptionsArr
  ,MAX(SC.ModifyDate) AS ModifyDate
FROM dbo.SubscriptionContent SC
INNER JOIN dbo.Subscription S ON S.SubscriptionId = SC.SubscriptionId
GROUP BY SC.ContentId

Then, in the C#, the field mappings on the indexer became:

new FieldMapping("ContentId") { TargetFieldName = nameof(Content.Id) },
new FieldMapping("SubscriptionsArr") { TargetFieldName = nameof(Content.Subscriptions),
    MappingFunction = new FieldMappingFunction("jsonArrayToStringCollection") }

The "jsonArrayToStringCollection" is a built in Azure mapping function as I linked above. Now my Subscriptions array is getting populated in the index.

UPDATE

While what I have above was working initially, the indexer would fail on subsequent runs if I set the HighWaterMarkChangeDetectionPolicy to be "ModifyDate". I was able to resolve this by wrapping the above query in a database view and altering the datasource to point to this view instead of the table.

发布评论

评论列表(0)

  1. 暂无评论