2016-11-03 12 views
1

Azure Search .Net SDK потенциально не возвращает все запрошенные результаты в запрос. В этом случае он вернет ContinuationToken как часть результата (DocumentSearchResult).Azure Search .Net SDK - Какой рекомендуемый способ комбинировать результаты типа DocumentSearchResult <T> после вызова ContinueSearch <T>?

From here:

Если Azure Поиск не может включать в себя все результаты в виде единого ответа, ответ возвращается будет включать продолжение маркер, который может быть передан в ContinueSearch, чтобы получить больше результатов. Дополнительную информацию см. В документе DocumentSearchResultBase.ContinuationToken. Обратите внимание, что этот метод не предназначен для того, чтобы помочь вам выполнить поиск поисковых запросов. Вы можете реализовать пейджинг с использованием параметров «Вверх» и «Пропустить» для метода поиска.

Как таковое рекомендуется, чтобы при возврате ContinuationToken был вызван ContinueSearch, чтобы получить остальные результаты.

Каков наилучший/рекомендуемый способ объединения двух объектов типа DocumentSearchResult<T> (один из исходных поисковых запросов, а другой из ContinueSearch), чтобы я мог возвратить все результаты вместе с потребителем?

Вот мой первый удар в нем («PerformSearch» метод будет называться, который должен возвращать все результаты):

private DocumentSearchResult<T> PerformSearch<T>(string searchText, SearchParameters searchParameters) where T : class 
    { 
     var searchIndexClient = GetSearchIndexClient<T>(); 
     var searchResults = searchIndexClient.Documents.Search<T>(searchText, searchParameters); 
     if (searchResults.ContinuationToken != null) 
     { 
      ContinueSearch(searchResults, searchIndexClient, searchResults.ContinuationToken); 
     } 

     return searchResults; 
    } 

    private void ContinueSearch<T>(DocumentSearchResult<T> previousResults, SearchIndexClient searchIndexClient, SearchContinuationToken continuationToken) where T : class 
    { 
     var results = searchIndexClient.Documents.ContinueSearch<T>(continuationToken); 
     previousResults.AddResults(results); 
     if (results.ContinuationToken != null) 
     { 
      ContinueSearch(previousResults, searchIndexClient, results.ContinuationToken); 
     } 
    } 

    public static void AddResults<T>(this DocumentSearchResult<T> first, DocumentSearchResult<T> second) where T : class 
    { 
     foreach (var searchResult in second.Results) 
     { 
      first.Results.Add(searchResult); 
     } 

     foreach (var facet in second.Facets) 
     { 
      first.Facets.Add(facet.Key, facet.Value); 
     } 
    } 

ответ

1

Вы можете объединить результаты, как у вас есть в вашем примере, но нет никакого смысла в объединении граней. Это связано с тем, что факс вычисляется по всем результатам запроса по каждому запросу, а не по фрагменту результатов, которые вы возвращаете. Если вы сделаете серию из ContinueSearch запросов, и индекс не будет изменен в течение этого времени, вы должны возвращать точно такие же грани каждый раз. Если ваш индекс меняется, и вы хотите получить самые свежие результаты факела, верните его последнему клиенту.

С точки зрения того, что рекомендуется делать, я на самом деле не рекомендую его, если вы не используете $top, чтобы ограничить общий размер результатов, или вы готовы иметь дело с очень большими наборами результатов. Azure Search ограничивает размер ответа по уважительным причинам, и эти причины, вероятно, относятся и к вам, если вы также пишете сервис.

Если вы пишете клиента, возможно, вам стоит попробовать реализовать итератор по результатам (IEnumerable<SearchResult<T>>), хотя вам придется возвращать дополнительную информацию (графы, количество документов) вне диапазона.

+0

Привет, Брюс, да, я использую верх. Это требование моего интерфейса с лазурным поиском. Из документации видно, что ограничения и продолжение Azure Search произвольны. Они не дают никаких обещаний о причинах или поведении и не рекомендуют использовать его для подкачки. Они только говорят «будьте готовы справиться с этим». Поэтому в этом случае я убеждаюсь, что я пейджинг правильно (сверху и снизу), и мне нужно убедиться, что я верну все возможные результаты для этой «страницы». Вот почему мой вопрос вызван. – richard

-1

Я не думаю, что вам нужны эти петли. Свойство фасетов представляет собой словарь, который не предполагающий никаких дубликатов означает, что вы можете комбинировать так:

dicA.Concat(dicB).ToDictionary(kvp => kvp.Key, kvp => kvp.Value) 
+0

Спасибо. Но это в значительной степени просто другой способ объединить любой словарь ... но является ли общий метод, который я использую правильно? Объединить их так? Или есть какой-то метод, который встроен в эти библиотеки, которые я пропустил? – richard

+0

Не об этом я знаю. Я полагаю, это зависит от того, что в конце дня вы хотите достичь. Вы можете создать библиотеку методов расширения, которая возвращает разные элементы по-разному, или класс, который работает над списком DocumentSearchResult. – Sentinel

+0

. В принципе, я хочу вернуть результаты моему потребителю, как будто поиск продолжения не требуется. Я не хочу, чтобы потребитель беспокоился об этом. Поэтому для потребителя это должно быть так, как будто все результаты поиска вернулись за один раз. – richard