Try our conversational search powered by Generative AI!

Get Title and Excerpt when applied Best Bets to a Typed Search?

Vote:
 

I have applied best bets to the Typed search as the Episerver developer documentation stated it. Is there a way to get the Best bet Title and the Excerpt (which are defined in the best bet edit mode in Epi Admin).

My implementation as of now,

// Sample Pages are stored in the Find Index
public class SamplePage : EPiServer.Core.PageData
    {
        public string SamplePageTitle { get; set; }
        public string SamplePageDescription { get; set; }
    }
public class SearchResult
    {
        public string Title { get; set; }
        public string Description { get; set; }
    }
// Getting the results
var result = client.Search<SamplePage>(GetLanguage(LanguageID))
                .For(Query, SearchHelper.QueryStringQueryAction)
                .Select(x => new SearchResult
                {
                    Title = x.SamplePageTitle, // Any way to have the Best Bet title ?
                    Description = x.SamplePageDescription // Any way to have the Best Bet Excerpt?
                })
                .ApplyBestBets()
                .Take(PageSize).GetResult();

As I have mentioned above, is there a way to get the Title and Excerpt?

Thanks.

#215900
Jan 17, 2020 5:03
Vote:
 

Hi guys, just realized nobody replied on this post. Does anybody know a fix for this issue?

#218059
Mar 05, 2020 6:23
Vote:
 

Hi Senura,

I believe you'll need to use UnifiedSearch. Once you're using that, the results will be of the type 'UnifiedSearchHit' and then the document on them will have the Title and Excerpt automatically.

i.e.

var unifiedSearch = _client.UnifiedSearch()
    .For(query)
    .ApplyBestBets()
    .GetResult();

var excerpt = unifiedSearch.Hits.First().Document.Excerpt;
var title = unifiedSearch.Hits.First().Document.Title;

Cheers,

- JJ

#218065
Mar 05, 2020 9:13
Vote:
 

@James Johnson, I appreciate your answer. However, isn't there a way to get the best bet title and excerpt using the ITypeSearch (Typed Search) ? Because the current search implementation is heavily configured with the ITypeSearch and moving to UnifiedSearch is not worth.

I am wondering why Episerver documentation has stated we could apply best bets to the typed search. What's the purpose of mentioning that in the documentation if we could not get the title and excerpt using the Typed Search ?

#218066
Edited, Mar 05, 2020 9:22
Vote:
 

Hi Senura,

You can apply the best bets to typed searches but as far as I'm aware, the results are more or less bundled in together, versus the unified search which has more data on if the result is a best bet or not.

Given the lack of other responses, you might be better off submitting a support ticket to support@episerver.com to try and find out directly from them if it is possible or not...?

Should it not be available for typed search, I think you'd need to do something like querying the 'BestBetRepository' and finding the one(s) that match your query phrase, then grabbing the Title and Excerpt from there.

Cheers.

- JJ

#218069
Mar 05, 2020 10:16
Vote:
 

Hi All,

I have exactly the same problem to solve. Did anyone find a solution to this?

Regards,

Paul

#256880
Jun 21, 2021 1:40
Vote:
 

Hi,

As far as the ApplyBestBets method goes, it is simply responsible for applying a relevancy boosting in the search algorithm where a Best Bet phrase matches a content instance.

Best Bet data is not indexed against products so is not returned in a typed search.

The Best Bets Title and Description defined in edit mode are for the benefit of editors. 

However your requirement is possible - just not out of the box so you need to be creative.

There is a BestBetsController that wraps the Find Rest API

 

Here's some code to get you started on a repository class that wraps the BestBetsController

    public class EpiFindBestBetRepository : IEpiFindBestBetRepository
    {
        private readonly BestBetsController _bestBetsController;

        public EpiFindBestBetRepository()
        {
            _bestBetsController = new BestBetsController
            {
                Request = new HttpRequestMessage(),
                Configuration = new HttpConfiguration()
            };
        }

        public bool Delete(string id)
        {
            var responseMessage = _bestBetsController.Delete(id);
            return responseMessage.IsSuccessStatusCode;
        }

        public int DeleteAll()
        {
            var responseMessage = _bestBetsController.GetList();
            var allBestBets = DeserializeResponse<BestBetsModel>(responseMessage).Hits;
            int itemsRemoved = allBestBets.Select(x => Delete(x.Id)).Count(y => y);

            return itemsRemoved;
        }

        public BestBetsModel Get(string id)
        {
            var responseMessage = _bestBetsController.Get(id);
            var bestBetModel = DeserializeResponse<BestBetsModel>(responseMessage);

            return bestBetModel;
        }

        public List<BestBetModel> List()
        {
            var responseMessage = _bestBetsController.GetList();
            var result = DeserializeResponse<BestBetsModel>(responseMessage).Hits;

            return result;
        }

        public List<BestBetModel> List(string siteId, string language, int from, int size)
        {
            var responseMessage = _bestBetsController.GetList($"siteid:{siteId}", from, size);
            var result = DeserializeResponse<BestBetsModel>(responseMessage).Hits;

            return result;
        }

        public bool Add(BestBetModel bestBetModel)
        {
            var responseMessage = _bestBetsController.Post(bestBetModel);
            return responseMessage.IsSuccessStatusCode;
        }

        private T DeserializeResponse<T>(HttpResponseMessage responseMessage)
        {
            var responseContentAsync = responseMessage.Content.ReadAsStringAsync();
            string response = responseContentAsync.Result;

            T httpResponse;
            using (var reader = new StringReader(response))
            {
                var jsonReader = new JsonTextReader(reader);
                httpResponse = Serializer.CreateDefault().Deserialize<T>(jsonReader);
            }

            return httpResponse;
        }
    }

You'll need to

  • Use the List() method to get all BestBets and store in cache
  • Create EPiServer Find conventions to index the BestBets against a product so you can pull it back
    • Consider how you reindex if a BestBet is added via the UI
  • Then use you convention to include this convention when getting the results. For example
var result = client.Search<SamplePage>(GetLanguage(LanguageID))
                .For(Query, SearchHelper.QueryStringQueryAction)
                .Select(x => new SearchResult
                {
                    Title = x.SamplePageTitle, 
                    Description = x.SamplePageDescription ,
                    BestBetTitle = x.BestBetTitle(),
                    BestBetDescription = x.BestBetDescription()
                })
                .ApplyBestBets()
                .Take(PageSize).GetResult();

 

#260151
Aug 05, 2021 13:51
Vote:
 

Thanks for this!

#263407
Sep 20, 2021 12:20
Vote:
 

No problem :)

#263411
Sep 20, 2021 13:01
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.