Efficiently retrieving all unique records for a facet value along with record counts in Algolia - algolia

I'm using Algolia to power search in my app. I have an index called prod_COACHES in which I have some records with an object key called speciality1.
The data structure for speciality1 looks like this:
I have enabled speciality1.itemName as an Algolia 'facet' so that I can filter on it. All good so far and working nicely. Now, in my Algolia dashboard I can see a nice bit of UI that shows me every unique facet (in this case my specialisations) along with the number of records for each facet:
As it happens, I want to show exactly this information on my own UI in my app but I'm not sure how to get this data from Algolia in the most efficient way. I'm using the client side AlgoliaSearch Javascript SDK. How do I run a search to retrieve every unique speciality1.itemName and the number of records for each unique speciality1.itemName so I can build my own UI just like the above?
I have gone through the docs and followed the examples but my question is really about finding the most efficient way to do this from someone who really knows Algolia well, rather than hack my own solution together. Thanks!

It looks like you've enabled attributesForFaceting on the attribute speciality1.itemName. You can retrieve the facet values for the given attribue with the search parameter facets. The Algolia response will now contain a map with value:count. Here is an example with the JavaScript client:
import algoliasearch from 'algoliasearch';
const client = algoliasearch('XXX', 'XXX');
const index = client.initIndex('XXX');
index.search('', {
facets: ['speciality1.itemName']
}).then(result => {
console.log(result.facets)
});
If you want to easily build a search UI, you should take a look at the InstantSearch libraries. It's built on top of Algolia to ease the state/ui management for such UI. Many flavours are available e.g. Vanilla, React.

Related

Issue in MongoDB document search

I am new to MongoDB. And I have the following issue on currently developing web application.
We have an application where we use mongoDB to store data.
And we have an API where we search for the document via text search.
As an example: if the user type “New York” then the request should send the all the available data in the collection to the keyword “New York". (Here we call the API for each letter typed.) We have nearly 200000 data in the DB. Once the user searches for a document then it returns nearly 4000 data for some keywords. We tried with limiting the data to 5 – so it returns the top 5 data, and not the other available data. And we tried without limiting data now it returns hundreds and thousands of data as I mentioned. And it causes the request to slow down.
At Frontend we Bind search results to a dropdown. (NextJs)
My question:
Is there an optimizing way to search a document?
Are there any suggestions of a suitable way that I can implement this requirement using mongoDB and net5.0?
Or any other Implementation methods regarding this requirement?
Following code segment shows the query to retrieve the data to the incomming keyword.
var hotels = await _hotelsCollection
.Find(Builders<HotelDocument>.Filter.Text(keyword))
.Project<HotelDocument>(hotelFields)
.ToListAsync();
var terminals = await _terminalsCollection
.Find(Builders<TerminalDocument>.Filter.Text(keyword))
.Project<TerminalDocument>(terminalFeilds)
.ToListAsync();
var destinations = await _destinationsCollection
.Find(Builders<DestinationDocument>.Filter.Text(keyword))
.Project<DestinationDocument>(destinationFields)
.ToListAsync();
So this is a classic "autocomplete" feature, there are some known best practices you should follow:
On the client side you should use a debounce feature, this is a most. there is no reason to execute a request for each letter. This is most critical for an autocomplete feature.
On the backend things can get a bit more complicated, naturally you want to be using a db that is suited for this task, specifically MongoDB have a service called Atlas search that is a lucene based text search engine.
This will get you autocomplete support out of the box, however if you don't want to make big changes to your infra here are some suggestions:
Make sure the field your searching on is indexed.
I see your executing 3 separate requests, consider using something like Task.WhenAll to execute all of them at once instead of 1 by 1, I am not sure how the client side is built but if all 3 entities are shown in the same list then ideally you merge the labels into 1 collection so you could paginate the search properly.
As mentioned in #2 you must add server side pagination, no search engine can exist without one. I can't give specifics on how you should implement it as you have 3 separate entities and this could potentially make pagination implementation harder, i'd consider wether or not you need all 3 of these in the same API route.

How to manually clear the cache of my algolia index?

I'm using the algolia client directly in my node js backend so i don't use instantsearch.js.
I can easily querying/indexing/updating etc. my algolia index but i can't find a way to clear the cache because my app always need to display an updated hits list in real time.
i've tried
client.initIndex('my index');
client.clearCache()
But without success. Always need to force unmount/remount manually my app to see the updated hits list.
Any solution ?
Its an old question but since there are no responses ....
Docs
Given the following instantiation:
const client = algoliasearch('H58KBL9VKQ', '••••••••••••••••••••');
const index = client.initIndex('your_index_name');
There are two methods.
client.clearCache() - when using multiple indices
index.clearCache() - when querying one index specifically
Note that BOTH return a Promise and both work only in the BROWSER, since the Node API doesn't cache results, there is no cache to clear.

Best practice for filtering data mongodb

I am looking into best -practices for returning search results. I have a search page that subscribes to a publication that returns a find based on the searched regex query in multiple fields. This gets put into the minimongo collection, on the client.
At this time, the way it is being handled is that facets are being set up from the subscription. My question is if the filtering for the pre-loaded results from the backend should be done client side, or if the query should be sent back.
Example :
Given a collection of fruits, i want to find all that have the color red. The server returns this, but I have facets based on the fruits. So, i have a checkbox for strawberries, apples, cherries, etc. If I click on the checkbox for cherries, should I just be filtering the current minimongo collection, or should I re-query?
Logically, I already have all the needed items in my collection that I could be filtering on, so I am not sure why I would need to hit the back-end. The only time I should hit the backend is if in the search, I type in a new query (such as blue), and the facets get re-done appropriately
If your original search is returning all matching documents then adding criteria on the client can just be done in your minimongo query if the fields on which the additional criteria were returned with the original search.
OTOH if the original search is returning a paginated list or just the top N results or if the required keys weren't included then you want to continue the search on the server.
In a traditional request-response system, you might also want to query the server each time if the underlying data was rapidly changing (ex: a reservations system). With Meteor the reactive nature of pub-sub means that the data on the client is being constantly refreshed with adds/changes/deletions via DDP over WebSocket.

Filters in Spring Data Neo4j 4

I am trying to use Neo4jOperations in Spring Data Neo4j 4.
Filters can be used in Neo4jOperations for retrieving data from NodeEntity.
Eg. I have a case where there are actors with "roles" in a movie. Now,Actor and Movie is a NodeEntity and roles is a RelationshipEntity. If i query a movie for a title using Filters, it does show me the relevant details.
I want to query details in the form - "Find me actors who have relationship (any relationship) in Movie 'Cloud Atlas'." I am not able to find a way to work for this using Filters.
Filters let you specify something like key-value pairs. Can I specify key value as "roles.movies.title" and query for the results?
Tried it this way, it does not work out.
Do not want to use Custom Query as we want to keep the query generic so that it can accomodate a lot of use cases. Attaching a custom query will mean that it can address only a specific case.
It is possible to implement your own FilterFunction, however, much simpler is to use a custom query for this. Example:
#Query("MATCH (a:Actor)-[]-(n:Movie {name: "Cloud Atlas"}) return n")
public List<Actor> findActorsRelatedToCloudAtlas()

SharePoint SOAP service GetListItem with respect to updated date?

Right now I am working on a project to fetch data from a SharePoint list using SOAP API. I tried and successfully fetches the complete list, but now I want to fetch some specific data that is updated after a specific date.
Is this possible to fetch such data using SOAP query. I can see last update filed when I view single item at the bottom. Is this some how possible to use that filed?
Yes you can use the Web Services to do lot of things just like filtering a list result. I don't know which language you use, but with JavaScript you can look at these two frameworks that should help you:
http://aymkdn.github.io/SharepointPlus/ : easy way to create your queries (I created it)
http://spservices.codeplex.com/ : the most popular framework but less easy to use (it's my point of view)
You can also look at the documentation on MSDN (the param to use is query): http://msdn.microsoft.com/en-us/library/lists.lists.getlistitems.aspx
At last found the answer,
The last update date and time can be retrieved from the list column "Modified".
The soap response will have the value in the attribute "ows_Modified".
Muhammad Usman