Reputation: 45
I am new to Azure Search, and I am currently setting up an environment to index images based on certain details.
I have set up an index that has, among other fields, a collection of complex fields I named details
.
To populate the details
field, I have set up an Azure Function as a WebApiSkill on my indexer, that receives the uri
as input and returns the details
.
According to the example from the documentation, the function receives a application/json
POST
request as follows:
{
"values": [
{
"recordId": "1",
"data": {
"uri": "..."
}
},
...
]
}
..and promptly returns an OkObjectResult
with the corresponding json
response:
{
"values": [
{
"recordId": "1",
"data": {
"details": [
{
"detailName": "...",
"detailRatio": "..."
}, {
"detailName": "...",
"detailRatio": "..."
}
]
}
},
...
]
}
My problem is, even though I followed the documentation on how to setup a custom skill for an indexer's skillset, and even though all of the above seem properly structured, the details
on my index's images remain unpopulated, and it just shows as an empty list.
Here are the results of an empty search on my index:
{
"@odata.context": "https://{search}.search.windows.net/indexes('{index}')/$metadata#docs(*)",
"value": [
{
"@search.score": 1,
"id": "aHR0CHM6Ly9yZWxhdGl...",
"uri": "{link}",
"details": []
}
}
By following the Azure Function's execution through console logs, it's possible to see that the indexer is indeed executing it and receiving the result, so I assume it's not a connection issue or the function's code's problem.
I would like to know if this is a common occurence? And if not, what steps should I take to try and figure out why the indexer refuses to properly populate the indexes?
Here are some code snippets from my indexes/indexer/skillset. I apologize for any confusion here, as some of these had to be made by code (C#) while others were made in the Azure Portal or by a POST request. To my knowledge, all of these boil down to the same, but I am currently in the process of converting all of these to POST requests.
Index:
{
"id": "...",
"uri": "...",
"details": [
{
"detailName": "...",
"detailRatio": "..."
}, {
"detailName": "...",
"detailRatio": "..."
}
]
}
Skillset:
{
"name": "...",
"description": "...",
"skills":
[
{
"@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
"uri": "https://{azure-function}.azurewebsites.net/api/{function}?code={code}",
"context": "/document",
"inputs": [
{
"name": "uri",
"source": "/document/uri"
}
],
"outputs": [
{
"name": "details",
"targetName": "details"
}
]
}
]
}
Indexer:
new Indexer(
name: indexerName,
dataSourceName: dataSourceName,
targetIndexName: indexName,
skillsetName: skillsetName,
fieldMappings: new List<FieldMapping>
{
new FieldMapping
{
SourceFieldName = "metadata_storage_path",
TargetFieldName = "uri"
}
},
schedule: new IndexingSchedule {
Interval = new TimeSpan(0, 10, 0)
},
parameters: new IndexingParameters
{
Configuration = new Dictionary<string, object>
{
["imageAction"] = "generateNormalizedImages"
}
}
);
Upvotes: 1
Views: 340
Reputation: 787
Your indexer definition is missing outputFieldMappings
to specify where the data for details
should come from. See https://learn.microsoft.com/en-us/rest/api/searchservice/create-indexer#outputfieldmappings
The context
of your skills is "/document"
and targetName
is "details"
, so the result will be at "/document/details"
.
"outputFieldMappings": [
{
"sourceFieldName": "/document/details",
"targetFieldName": "details"
}
]
Upvotes: 2