2015-08-25 4 views
4

Я выгружаю свою функцию поиска в реляционной базе данных в Azure Search. Таблицы My Products содержат такие столбцы, как serialNumber, PartNumber и т. Д. (Может быть несколько serialNumbers с тем же номером partNumber).Отличные значения в Azure Search Suggestions?

Я хочу создать предложение, которое может автозаполнять partNumbers. Но в моем сценарии я получаю много дубликатов в предложениях, потому что совпадение partNumber было найдено в нескольких записях.

Как я могу решить эту проблему?

ответ

3

Предлагаемый API предлагает документы, а не запросы. Если вы повторяете информацию partNumber для каждого серийного номера в своем индексе, а затем предлагаете на основе partNumber, вы получите результат для каждого соответствующего документа. Вы можете увидеть это более четко, включив ключевое поле в параметр $ select. Azure Search устранит дубликаты внутри одного документа, но не через документы. Вам нужно будет сделать это на стороне клиента или создать вторичный индекс partNumbers только для предложений.

См. this forum thread для более подробного обсуждения.

Кроме того, не стесняйтесь голосовать по телефону this UserVoice item, чтобы помочь нам расставить приоритеты в предложениях.

0

Я сам столкнулся с этой проблемой. Мое решение не связано с новым индексом (это будет только беспорядочным и стоить нам денег).

Мое занятие - это цикл while, добавляющий «UserIdentity» (в вашем случае «partNumber») к фильтру и повторный поиск до тех пор, пока не будет выполнен мой верхний предел или не будет больше предложений:

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; 
}