Implementing search feature for OXINION search tab
I’ve been wondering how to implement search feature everytime. Actually was a bit scared so its not familiar.
Since i’ve been working similar to Yelp, I mocked Yelp’s Fusion API. On Yelp, this is available to search location=london or &latitude=51&longitude=0.
GET https://api.yelp.com/v3/autocomplete?text=del&latitude=37.786882&longitude=-122.399972
issue 1. How to handle space in search terms or location name
encodeURI()
URLSearchParams
interface SearchQuery {
term?: string;
location?: string;
}
const search = () => {
const router = useRouter();
let { term:searchTerm, location: searchLocation }:SearchQuery = router.query;
const term = decodeURIComponent(searchTerm);
const location = decodeURIComponent(searchLocation);
console.log(term);
Read this blog for converting location text into lat/lng values for details
Get term and location text from FE.
try {
const result = await geocode.geocode(location);
if (!result.length) {
return res.status(404).json({ msg: "Invalid location" });
}
coordinates = [result[0].latitude, result[0].longitude];
} catch (err) {
return res.status(404).json({ msg: "Invalid location" });
}
console.log(coordinates);
Find posts that match terms and location
// Find the posts that match the term and are within a certain distance of the provided coordinates
const posts = await Post.find({
term: { $regex: term, $options: "i" },
location: {
$near: {
$geometry: {
type: "Point",
coordinates: [coordinates[1], coordinates[0]],
},
$maxDistance: 5000, // distance in meters
},
},
});
The find()
method is used to search for posts that match the provided term
using a regular expression. The $regex
operator is used to match the term
to the term
field of the Post
model. The $options: 'i'
is used to make the match case-insensitive.
For example, if the user is searching for the term “pizza”, the API will return all posts that have the word “pizza” in the term
field, regardless of whether it's uppercase or lowercase.
The API also uses the $near
operator in the find()
method to perform a geospatial search, which finds all posts that are within a certain distance of the provided coordinates. The $geometry
object is used to specify the point for which to search nearby documents.
In summary, the code provided searches for all the post which have term matching the given term
and are within a certain distance (5000 meters) of the provided coordinates, and it is returning them as a JSON object in the response.
it performs the following operations:
- It gets the
term
andlocation
query parameters from the request. - It uses the
geocode
package to convert thelocation
string to latitude and longitude coordinates. - It creates an index on the
location
field of thePost
model using thecreateIndexes()
method, so that geospatial queries can be performed on it. - It performs a search on the
Post
model using thefind()
method. It searches for posts that match the providedterm
using a regular expression, and are within a certain distance of the provided coordinates. - It returns the search results in the response.
To make it better,
- add some validation for the input in React frontend.
- adding some error handling for cases where the
geocode
package fails to parse the location string