1

I'm working on a personal Android application in Kotlin, and I want to implement an InstantSearch. I have the following record construct in Algolia:

{
  "creationTime": 1566396861797,
  "description": "It's my second home now...",
  "imagePath": "https://firebasestorage.googleapis.com/.......",
  "memoryId": "-LmoWe8PEqCs0Szv9KKJ",
  "memoryTitle": "Second visit",
  "userId": "vIWJgFpnUSeZJw3wjrJeEAxbNoE2",
  "imageLabels": [
    "Property",
    "Furniture",
    "City",
    "Human settlement",
    "Real estate",
    "Roof",
    "Room",
    "Skyline",
    "Building",
    "Metropolitan area",
    "Sky",
    "Balcony",
    "Apartment"
  ],
  "objectID": "-LmoWe8PEqCs0Szv9KKJ"
}

In my InstantSearch I want to provide a search that present only records with userId value identical to this specific user that send the query. First I added the userId to the attributes for faceting in the dashboard. I don't know exactly how to continue from this point. I don't know how to filter records at query time.

Here is my ViewModel:

class MyViewModel : ViewModel() {
    val client = ClientSearch(ApplicationID("*****"), APIKey("*******"), LogLevel.ALL)
    val index = client.initIndex(IndexName("memory_diary"))
    val searcher = SearcherSingleIndex(index)
    val adapterMemory = MemoryAdapter()
    val dataSourceFactory = SearcherSingleIndexDataSource.Factory(searcher) { hit ->
        Memory(
                hit.json.getPrimitive("userId").content,
                hit.json.getPrimitive("objectID").content,
                hit.json.getPrimitive("memoryTitle").content,
                hit.json.getPrimitive("description").content,
                hit.json.getPrimitive("creationTime").content.toLong(),
                hit.json.getPrimitive("imagePath").content,
                hit.json.getArray("imageLabels").content.map { jsnelm -> jsnelm.content }
        )
    }


    val pagedListConfig = PagedList.Config.Builder().setPageSize(50).build()
    val memories: LiveData<PagedList<Memory>> = LivePagedListBuilder(dataSourceFactory, pagedListConfig).build()

    val searchBox = SearchBoxConnectorPagedList(searcher, listOf(memories))
    val stats = StatsConnector(searcher)
    val filterState = FilterState()
    val connection = ConnectionHandler()

    init {
        connection += searchBox
        connection += stats
        connection += filterState.connectPagedList(memories)
    }

    override fun onCleared() {
        super.onCleared()
        searcher.cancel()
        connection.disconnect()
    }
}

I thougt maybe there is a function that filter records in SearcherSingleIndexDataSource.Factory but I didn't find something like this.

So how can I do that?

Dvir Barzilay
  • 87
  • 1
  • 11
  • Please don't tag questions with the android-studio tag just because you use it: the Android Studio tag should **only** be used when you have questions about the IDE itself, and not any code you write (or want to write) in it. See [when is it appropriate to remove an IDE tag](https://meta.stackoverflow.com/a/315196/6296561), [How do I avoid misusing tags?](https://meta.stackoverflow.com/q/354427/6296561), and [the tagging guide](/help/tagging). Use [android] or other relevant tags instead. – Zoe Aug 28 '19 at 21:07

2 Answers2

0

To learn how to inject filters at query time, please refer to our FilterState documentation.

In your case, you could write something like this:

    filterState.notify {
       add(FilterGroupID(), Filter.Facet(Attribute("userId"), "user_id_value"))
    }

Let me know if this resolves your issue.

Kiran Maniya
  • 8,453
  • 9
  • 58
  • 81
0

I implemented the filter without having to wait for user input and it worked

I followed algolia docs but skipping some parts https://www.algolia.com/doc/guides/building-search-ui/getting-started/android/

The filter state will need an Attribute: In your case userId.

Define an operator and a filterFacet

The Searcher connects itself to the FilterState, and applies its filters with every search.

connection += searcher.connectFilterState(filterState)

In resume your view model looks like this:

val filterState = FilterState()
val filterGroupID = FilterGroupID("myGroup", FilterOperator.And)
val userId = Attribute("userId")
val filterUserId =  Filter.Facet(userId, "your_user_id")
   
val connection = ConnectionHandler()
    
init {
   filterState.add(filterGroupID, owner)
   connection += searchBox

   connection += searcher.connectFilterState(filterState)
   connection += filterState.connectPagedList(memories)
}