Sorting results for InstantSearch

Hello everyone,

I hope you are doing fine. I want to sort my search results according to a particular attribute.
I just wanted to verify if my approach is fine:

 filterState[or: "groupName"].add(Filter.Facet(attribute: "challengeId", stringValue: challengeObject.id!))
 sortByConnector = .init(searcher: participationIndexSearcher, indicesNames: ["rating"], selected: 0)
 sortByConnector.connect()
        
 participationIndexSearcher.connectFilterState(filterState)
 participationIndexSearcher.search()

I am not sure, if even sortByConnector.connect() is needed but to explain you my goal, I want to sort after the ranking attribute.

Thanks in advance!
Best regards,
Kaan

Just to update on my post. I changed my code a bit

    private func setupInstantSearchSettings() {
        singleIndexHitsInteractor.connectController(self)
        sortByConnector = .init(searcher: participationIndexSearcher, indicesNames: [ 
       "default","most_rated","recent"], selected: 0)
    }

I created three replicas of my original index and configured the sortBy attribute directly on the dashboard.
The function setupInstantSearchSettings is called once in my view controller.
The actual search is performed in another method

 private func searchMostRatedParticipationContents() {
        filterState[or: "groupName"].add(Filter.Facet(attribute: "challengeId", stringValue: challengeObject.id!))
        
        sortByConnector.selectedIndexName = "most_rated"
        participationIndexSearcher.connectFilterState(filterState)
        participationIndexSearcher.search()
   }

Using the code above, I don’t get ay results at all.

Update again :smiley:
The reason why I was not get any results was, because following line was missing:

        singleIndexHitsInteractor.connectSearcher(participationIndexSearcher)

Now, I am getting results back but somehow, they are not sorted. The only way how I checked the sorting was to print out

hitsSource!.getCurrentHits()

I wanted to have a descending order of the rating attribute but it always prints the one where rating is has the value 0. There are also other rating with a higher value.

Hello guys, any news on this?

Hi @vladislav.fitc , could you help me here, please? :slight_smile: Thanks!

Hi @kaan548 ,

Could you try to test your application with the code of this demo? I hope it will help to detect what’s missing in your implementation.
Let me know if it helps.

Hi @vladislav.fitc , many thanks for coming back on this issue. I am still struggling with it.

I have checked already the demo code. I can see some difference such as:

    controller.sortByConnector.connectController(selectIndexAlertController, presenter: { self.title(for: $0.name) } )
    controller.sortByConnector.interactor.onSelectedComputed.subscribe(with: self) { (viewController, index) in
      index.flatMap { viewController.controller.indexes[$0] }.flatMap(viewController.setChangeIndexButton)
    }

But I assume that I don’t need a UI controller to switch between indices, right? Because Instead of displaying the selectIndexAlertController on the UI, I switch between indices by pressing other buttons on the screen.
Do you have any other suggestions?

Hi @vladislav.fitc , do you have any other inputs for me? :slight_smile:

I also saw this post

Could it be related somehow? Do you know any issues on server side?

Thanks!

Sorry, I missed your reply.
You are not obliged to use the SelectIndexController. You can build your own implementation of SelectableSegmentController protocol which will call onClick closure when you press a button on the screen. Then you should connect this controller to the SortByConnector using connectController function.
The documentation is here, just replace the SelectIndexController with your own implementation.

Since the sorting just switches the index to search in, it’s not a backend problem. I just tested the sort by demo in the demo application and it works well.

Hi @vladislav.fitc ,

many thanks for your replies so far. If there is a way to highlight your contribution, please let me know. You deserve a very good feedback.

I have two questions:

  1. How would I check if the sorting works properly? If I do hitsSource?.numberOfHits() , will it give the sorted results?

2.) I can have my own implementation of SelectableSegmentController but is it really can or must? :slight_smile: Can I switch indices by simply doing it like:

sortByConnector.selectedIndexName = “most_rated”

and then apply

participationIndexSearcher.connectFilterState(filterState)
participationIndexSearcher.search()

  1. You can check the hitsSource?.getCurrentHits() output to fetch the list of currently loaded hits.

  2. If the provided blocks don’t suit you, you are free to implement the logic on your own, or just use some of them. If you want to set the index manually via SortByConnector:

sortByConnector.selectedIndexName = “most_rated”sortByConnector.interactor.computeSelected(selecting: 1) // 1 is the index of the “most_rated” in the list
participationIndexSearcher.search()

It’s actually not that straightforward if you don’t build a SelectableSegmentController implementation. We will add the necessary clarification in the documentation.

Also I advise you to make sure that you call participationIndexSearcher.connectFilterState(filterState) just once (for example, in the viewDidLoad method) and not on each button tap.

It worked. Thanks @vladislav.fitc :smiley:

Glad to hear that :slight_smile:

<SortBy
       defaultRefinement="??"
            items={[
              { value: '??', label: 'Viwed Count' },  
            ]}/>

I want to know which parameter should I pass here. Is it primary index? Where will I get it on algolia dashboard?