Azure 搜索建议中的不同值?
Distinct values in Azure Search Suggestions?
我正在将关系数据库上的搜索功能卸载到 Azure 搜索。我的产品表包含 serialNumber、PartNumber 等列。(可以有多个具有相同 partNumber 的 serialNumbers)。
我想创建一个可以自动完成 partNumbers 的建议器。但在我的场景中,我得到了很多重复的建议,因为在多个条目中找到了 partNumber 匹配项。
我该如何解决这个问题?
建议 API 建议文档,而不是查询。如果您为索引中的每个 serialNumber 重复 partNumber 信息,然后根据 partNumber 进行建议,您将获得每个匹配文档的结果。通过在 $select 参数中包含键字段,您可以更清楚地看到这一点。 Azure 搜索将消除同一文档中的重复项,但不会消除跨文档的重复项。您将必须在客户端执行此操作,或者构建 partNumbers 的二级索引以获取建议。
有关更深入的讨论,请参阅 this forum thread。
另外,欢迎对 this UserVoice item 投票,帮助我们优先改进建议。
我自己也面临这个问题。我的解决方案不涉及新索引(这只会变得混乱并让我们花钱)。
我对此的看法是将 'UserIdentity'(在您的情况下为 'partNumber')添加到过滤器,然后重新搜索直到满足或不满足我的 take/top-limit存在更多建议:
public async Task<List<MachineSuggestionDTO>> SuggestMachineUser(string searchText, int take, string[] searchFields)
{
var indexClientMachine = _searchServiceClient.Indexes.GetClient(INDEX_MACHINE);
var suggestions = new List<MachineSuggestionDTO>();
var sp = new SuggestParameters
{
UseFuzzyMatching = true,
Top = 100 // Get maximum result for a chance to reduce search calls.
};
// Add searchfields if set
if (searchFields != null && searchFields.Count() != 0)
{
sp.SearchFields = searchFields;
}
// Loop until you get the desired ammount of suggestions, or if under desired ammount, the maximum.
while (suggestions.Count < take)
{
if (!await DistinctSuggestMachineUser(searchText, take, searchFields, suggestions, indexClientMachine, sp))
{
// If no more suggestions is found, we break the while-loop
break;
}
}
// Since the list might me bigger then the take, we return a narrowed list
return suggestions.Take(take).ToList();
}
private async Task<bool> DistinctSuggestMachineUser(string searchText, int take, string[] searchFields, List<MachineSuggestionDTO> suggestions, ISearchIndexClient indexClientMachine, SuggestParameters sp)
{
var response = await indexClientMachine.Documents.SuggestAsync<MachineSearchDocument>(searchText, SUGGESTION_MACHINE, sp);
if(response.Results.Count > 0){
// Fix filter if search is triggered once more
if (!string.IsNullOrEmpty(sp.Filter))
{
sp.Filter += " and ";
}
foreach (var result in response.Results.DistinctBy(r => new { r.Document.UserIdentity, r.Document.UserName, r.Document.UserCode}).Take(take))
{
var d = result.Document;
suggestions.Add(new MachineSuggestionDTO { Id = d.UserIdentity, Namn = d.UserNamn, Hkod = d.UserHkod, Intnr = d.UserIntnr });
// Add found UserIdentity to filter
sp.Filter += $"UserIdentity ne '{d.UserIdentity}' and ";
}
// Remove end of filter if it is run once more
if (sp.Filter.EndsWith(" and "))
{
sp.Filter = sp.Filter.Substring(0, sp.Filter.LastIndexOf(" and ", StringComparison.Ordinal));
}
}
// Returns false if no more suggestions is found
return response.Results.Count > 0;
}
public async Task<List<string>> SuggestionsAsync(bool highlights, bool fuzzy, string term)
{
SuggestParameters sp = new SuggestParameters()
{
UseFuzzyMatching = fuzzy,
Top = 100
};
if (highlights)
{
sp.HighlightPreTag = "<em>";
sp.HighlightPostTag = "</em>";
}
var suggestResult = await searchConfig.IndexClient.Documents.SuggestAsync(term, "mysuggestion", sp);
// Convert the suggest query results to a list that can be displayed in the client.
return suggestResult.Results.Select(x => x.Text).Distinct().Take(10).ToList();
}
进入前 100 名并使用 distinct 后,它对我有用。
您可以使用自动完成 API 来默认分组。但是,如果您需要更多字段以及结果,例如 partNo 加描述,它不支持它。 partNo 将是不同的。
我正在将关系数据库上的搜索功能卸载到 Azure 搜索。我的产品表包含 serialNumber、PartNumber 等列。(可以有多个具有相同 partNumber 的 serialNumbers)。
我想创建一个可以自动完成 partNumbers 的建议器。但在我的场景中,我得到了很多重复的建议,因为在多个条目中找到了 partNumber 匹配项。
我该如何解决这个问题?
建议 API 建议文档,而不是查询。如果您为索引中的每个 serialNumber 重复 partNumber 信息,然后根据 partNumber 进行建议,您将获得每个匹配文档的结果。通过在 $select 参数中包含键字段,您可以更清楚地看到这一点。 Azure 搜索将消除同一文档中的重复项,但不会消除跨文档的重复项。您将必须在客户端执行此操作,或者构建 partNumbers 的二级索引以获取建议。
有关更深入的讨论,请参阅 this forum thread。
另外,欢迎对 this UserVoice item 投票,帮助我们优先改进建议。
我自己也面临这个问题。我的解决方案不涉及新索引(这只会变得混乱并让我们花钱)。
我对此的看法是将 'UserIdentity'(在您的情况下为 'partNumber')添加到过滤器,然后重新搜索直到满足或不满足我的 take/top-limit存在更多建议:
public async Task<List<MachineSuggestionDTO>> SuggestMachineUser(string searchText, int take, string[] searchFields)
{
var indexClientMachine = _searchServiceClient.Indexes.GetClient(INDEX_MACHINE);
var suggestions = new List<MachineSuggestionDTO>();
var sp = new SuggestParameters
{
UseFuzzyMatching = true,
Top = 100 // Get maximum result for a chance to reduce search calls.
};
// Add searchfields if set
if (searchFields != null && searchFields.Count() != 0)
{
sp.SearchFields = searchFields;
}
// Loop until you get the desired ammount of suggestions, or if under desired ammount, the maximum.
while (suggestions.Count < take)
{
if (!await DistinctSuggestMachineUser(searchText, take, searchFields, suggestions, indexClientMachine, sp))
{
// If no more suggestions is found, we break the while-loop
break;
}
}
// Since the list might me bigger then the take, we return a narrowed list
return suggestions.Take(take).ToList();
}
private async Task<bool> DistinctSuggestMachineUser(string searchText, int take, string[] searchFields, List<MachineSuggestionDTO> suggestions, ISearchIndexClient indexClientMachine, SuggestParameters sp)
{
var response = await indexClientMachine.Documents.SuggestAsync<MachineSearchDocument>(searchText, SUGGESTION_MACHINE, sp);
if(response.Results.Count > 0){
// Fix filter if search is triggered once more
if (!string.IsNullOrEmpty(sp.Filter))
{
sp.Filter += " and ";
}
foreach (var result in response.Results.DistinctBy(r => new { r.Document.UserIdentity, r.Document.UserName, r.Document.UserCode}).Take(take))
{
var d = result.Document;
suggestions.Add(new MachineSuggestionDTO { Id = d.UserIdentity, Namn = d.UserNamn, Hkod = d.UserHkod, Intnr = d.UserIntnr });
// Add found UserIdentity to filter
sp.Filter += $"UserIdentity ne '{d.UserIdentity}' and ";
}
// Remove end of filter if it is run once more
if (sp.Filter.EndsWith(" and "))
{
sp.Filter = sp.Filter.Substring(0, sp.Filter.LastIndexOf(" and ", StringComparison.Ordinal));
}
}
// Returns false if no more suggestions is found
return response.Results.Count > 0;
}
public async Task<List<string>> SuggestionsAsync(bool highlights, bool fuzzy, string term)
{
SuggestParameters sp = new SuggestParameters()
{
UseFuzzyMatching = fuzzy,
Top = 100
};
if (highlights)
{
sp.HighlightPreTag = "<em>";
sp.HighlightPostTag = "</em>";
}
var suggestResult = await searchConfig.IndexClient.Documents.SuggestAsync(term, "mysuggestion", sp);
// Convert the suggest query results to a list that can be displayed in the client.
return suggestResult.Results.Select(x => x.Text).Distinct().Take(10).ToList();
}
进入前 100 名并使用 distinct 后,它对我有用。
您可以使用自动完成 API 来默认分组。但是,如果您需要更多字段以及结果,例如 partNo 加描述,它不支持它。 partNo 将是不同的。