【问题标题】:Distinct values in Azure Search Suggestions?Azure 搜索建议中的不同值?
【发布时间】:2015-11-19 08:01:48
【问题描述】:

我正在将关系数据库上的搜索功能卸载到 Azure 搜索。我的产品表包含序列号、部件号等列。(可以有多个序列号具有相同的部件号)。

我想创建一个可以自动完成零件编号的建议器。但在我的场景中,由于在多个条目中找到了 partNumber 匹配项,因此建议中有很多重复项。

我该如何解决这个问题?

【问题讨论】:

    标签: azure azure-cognitive-search


    【解决方案1】:

    Suggest API 建议文档,而不是查询。如果您为索引中的每个序列号重复 partNumber 信息,然后根据 partNumber 建议,您将获得每个匹配文档的结果。通过在 $select 参数中包含关键字段,您可以更清楚地看到这一点。 Azure 搜索将消除同一文档中的重复项,但不会跨文档消除。您必须在客户端执行此操作,或者构建 partNumbers 的二级索引以获取建议。

    请参阅this forum thread 进行更深入的讨论。

    另外,请随时对this UserVoice item 投票,以帮助我们确定对建议的改进优先级。

    【讨论】:

      【解决方案2】:

      我自己也面临这个问题。我的解决方案不涉及新索引(这只会变得混乱并花费我们的钱)。

      我对此的看法是一个 while 循环,将“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;
      }
      

      【讨论】:

        【解决方案3】:
         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 后,它对我有用。

        【讨论】:

          【解决方案4】:

          默认情况下,您可以使用自动完成 API 进行分组。但是,如果您需要更多字段以及结果,例如 partNo 加上描述,它不支持它。不过,partNo 将是不同的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-04-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-12
            相关资源
            最近更新 更多