در حال بارگذاری ...

Organizing Playground Routes0:03

Now before we perform our first search, why don't we do just a little bit of organization mostly to make it as easy as possible for you to copy and paste whatever you need. So here's what I'll do. I'm gonna copy this route and I'm gonna rename it to, well, what did we do here? We created a collection. So I will call it createCollection. Now keep in mind these are not endpoints you actually want in your app.

Now keep in mind these are not endpoints you actually want in your app. We're just using this, uh, as a, as a playground. If you wanted to configure these as artisan commands, that would be fine as well. They're not intended to keep, just to play around. Okay, so now if I paste in the next one, I will call this one importCollection. And each one will be like a self-contained snippet, uh, for how to perform an action.

And each one will be like a self-contained snippet, uh, for how to perform an action. So for example, at the top to create a Collection, here's what we need. We'll say collection created. Alright, next to import a Collection. Once again, we are duplicating here, but that's okay. We already have our schema and we've already imported it. So all we would have to do is get the database, get the collection, and then we would, uh, defer to books.

Creating Search Endpoint1:06

So all we would have to do is get the database, get the collection, and then we would, uh, defer to books and import them like so. Alright, so now we're gonna do a third one and this is going to be our playground for searching, um, a collection. Alright, so here's what we do. We have our clients, we've already imported these so I can get rid of it. And let's get going. We'll say clientCollections

we've already imported these so I can get rid of it. And let's get going. We'll say client collections books is the name of our collection and I'm gonna search through our documents or search through our table rows. So documents search, alright, what is the query? Uh, let's start by hard coding it. And then of course later we will make that available through the query string. So yeah, maybe we can search for, um,

through the query string. So yeah, maybe we can search for, um, a book I like is called Dark Matter. So let's start by looking for dark as our query. All right, this will give us our results and why don't we dd the results and have a look in the browser. So take note of this endpoint, switch back, go to search collection. And we get no search fields specified for the query.

Specifying Search Fields2:11

to search collection. And we get no search fields specified for the query. So here's what's going on. It's saying, Hey, you're trying to query against this collection, but you didn't tell me what we're looking in. Are we looking through the title? Are we looking through the author? We need to be explicit about that, right? So let's switch back

We need to be explicit about that, right? So let's switch back and add our search fields, query buy. And we're just gonna look at the title for now. That's the only thing I want factored into the equation. All right, so let's see. Oh, this is interesting. Zero found and zero hits. That's not right. So here's what I'm thinking. Uh, maybe we made a mistake importing our data. So here's what we can do. Let's once again run that command

Debugging Import Errors2:47

Uh, maybe we made a mistake importing our data. So here's what we can do. Let's once again run that command to check our books collection. And yeah, this shows all of the schema, like the name, author, title, publication year, but at the very bottom we should also see, aha, here it is. So yeah, at the bottom it shows the number of documents that are available here and it's set to zero even though we performed that import. So here's what I'm thinking, we probably have some

to zero even though we performed that import. So here's what I'm thinking, we probably have some glitch related to our schema. So let's scroll up to where we import the collection. So API key, this looks good. Yes, yes, yes. Yeah, it must be something related to the import. So here's what we can do. We can return the response and this will show us for each document, um, if it was successful, if there was an error. So here's what I'll do. Let's run this route again,

if it was successful, if there was an error. So here's what I'll do. Let's run this route again, but then dd the response and it'll tell us if we, uh, misconfigured something, import Collection and aha, we found it. We should have checked for this. So yeah, we can see we have a 400 because the author has been declared in the schema, but it wasn't found in the document. So it's really important that we sync these up.

but it wasn't found in the document. So it's really important that we sync these up. So of course in this case, I know exactly what the problem was when we defined the schema right up here. I used the name author, but of course because it is uh, potentially an array, the actual schema key is authors. And we can verify this by looking in the books database and we can see, yep, it was set to authors.

And we can verify this by looking in the book's database and we can see, yep, it was set to authors. So this was my mistake, but you know what? I'm gonna keep it in the course because, uh, well it is just a great example of how you can go about debugging, uh, some of these things that you might run into in your own projects. Okay, very cool. So let's do this. Let's reimport this. And here's what I can do, because we have this handy dandy, uh, playground route, what I will do is at the very start

And here's what I can do, because we have this handy dandy, uh, playground route, what I will do is at the very start before I run this, I'm going to uh, say for the Books collection, just delete it. We're gonna start entirely from scratch. So delete the existing books collection and then build up a new one. Okay, switch back. Let's go to create collection. There we go. Next I will import the collection. Yep, lots of success truths.

There we go. Next I will import the collection. Yep, lots of success truths. So if I go back to the command line and we run this again, you'll see that now we have almost 10,000 documents and this is what we lent. Okay, so now sorry about that. So now if we swap back down to the very bottom, uh, we can try this out. So right down here, let's get rid of that. Let's search the collection.

So right down here, let's get rid of that. Let's search the collection. We search for dark and this time let's see what we get. Alright, now we get 134 results. Let's have a look at the hits. So what is the top most hit? Let's see, we have our document, which again, I'm just drilling this into you. Think of it like a table row in your head. And sure enough we can see the top result is a book called, uh, Dead Until Dark.

And sure enough we can see the top result is a book called, uh, dead until Dark. And the author is Charla Harris. Let's just keep going. Let's look at one more. Uh, we can see this one's called Dark Places. Now here's the cool thing that typesense offers. You'll see a highlight section. So this is exactly what you think it is. It will show us the title, but it will highlight the relevant part.

It will show us the title, but it will highlight the relevant part that matches your search query. So you'll see if I go into highlight for title, here is our snippet. So notice we have the same title, but it wraps uh, the part that matches your query within mark tags. And then when you display your results, you can highlight it, set a yellow background, uh,

And then when you display your results, you can highlight it, set a yellow background, uh, you've seen things like that a million times, right? So if I were to change this to DR and if we come back and refresh, now of course only the DAR portion will be highlighted as you can see right here. Very cool. Alright, so now let's do this. Let's swap out this hardcoded query with something that comes from the request. So I'll say look in the query string for Q.

that comes from the request. So I'll say look in the query string for Q and of course, yeah, you probably wanna validate this as well, but we're gonna skip over that just uh, in the playground phase of our learning. Okay, so now for example, if I were to search for Q equals Harry, well I would imagine that Harry Potter is going to be the top result. Let's see, open up the documents and sure enough we get Harry Potter.

Let's see, open up the documents and sure enough we get Harry Potter and the philosophers stone. Very cool. But now here's something to consider. If I instead search for Rowling, the writer of Harry Potter, and if we give this a run, well we get just one result. And you know what? I bet it's not what we expect. We take a look and sure enough we get the howling. And this is actually, uh, an interesting little note here. It matched howling.

And this is actually, uh, an interesting little note here. It matched howling because it's assuming that possibly we have a typo here. So type sense will take that into account even if maybe you have a mistake here or there, it's smart enough to figure out what you possibly uh, meant. Now in this case, I search for rallying and maybe I would still expect Harry Potter to show up, but it doesn't in this case.

and maybe I would still expect Harry Potter to show up, but it doesn't in this case. And if we switch back, we can see why, right? We are querying by the title. We didn't say query by the author, we said no. The only thing I want you to use here is the title of the book, not the authors. So here's what I could do. I could do a commas separated list here and now I can say, yeah, look in the title, but also look in that array of authors.

list here and now I can say, yeah, look in the title, but also look in that array of authors. So if I come back and we give this another run this time we have many more results, go to the very top, go into the document. And yet once again, now even though I'm searching for rallying it matched it, and of course that's the most popular book in the world. So, uh, it brings that up as the number one result. Check the author. And we have JK Rowling.

Mapping Search Results8:27

So, uh, it brings that up as the number one result. Check the author. And we have JK Rowling and I dunno, this, this is maybe like the translation, uh, for this edition. I'm not entirely sure. Alright, so let's do this, let's wrap this up. Uh, we have our results. So I'm gonna wrap this within a Laravel collection and I just wanna filter this down here. So let's go into the hits and then this is an array.

and I just wanna filter this down here. So let's go into the hits and then this is an array. And I'm gonna say foreach hit I want to pluck the documents. And maybe let's just grab the title of the book. For now. I just want an array or a collection, a Laravel collection that contains only the titles, uh, for the results. So here's what I might do. I'm gonna map over it and for each hit I'm going to return the document. All right? So now we're gonna have a collection

and for each hit I'm going to return the document. All right? So now we're gonna have a collection of only the documents. And then within the document, I'm just gonna grab the title. So why don't we say hit.document.title. Alright, and hopefully we did everything correctly here. Let's return the titles, come back, give it another run. And sure enough, if we pretty print, we have an array in this case of all of the matches. All right? So notice that philosopherStone comes first.

Sorting and Pagination Options9:36

we have a an array in this case of all of the matches. All right? So notice that philosopher stone comes first and then the cursive child comes last. This is kind of what we would naturally expect, but of course you have full control over the sort order. So why don't we play around with this? So here's what we can do. I can say sortBy and we're gonna provide some kind of, um, schema value that we want to sort according to.

and we're gonna provide some kind of, um, schema value that we want to sort according to. Again, do we wanna sort according to the ratings count, uh, you could even sort according to a release, share any kind of number. Uh, by default we'll work just fine. Uh, we can even take that further. But as initial starting point, think of things that are numbers that will help you. So for example, if I want to sort by

that are numbers that will help you. So for example, if I want to sort by ratingsCount in descending order, this is how we might do this. So if I come back and give this a refresh, we can see this result here. Why don't we reverse it? Let's do ascending order, which means the least ratingsCount will come first. Once again, give it a refresh and now we can see yes, sure enough we're gonna get some.

Once again, give it a refresh and now we can see yes, sure enough we're gonna get some kind of book about that universe. But not one of the core books will come first because of course those will have, uh, lesser ratings than the actual novels. So everything's working great. And yeah, you have full control here. You can even combine things. So for example, by default typeSense has this thing

You can even combine things. So for example, by default type Sense has this thing called textMatch. And this is just a special keyword that represents how closely the query matched, uh, the, the results here. So I could say textMatch in descending order. And yeah, this is gonna give you, um, possibly what you expect. So notice, yeah, in this case it's not really factoring in the ratingsCount.

So notice, yeah, in this case it's not really factoring in the ratings count because we overrode that we said no, just focus on the text match. And in this case, even though Harry Potter and the Philosopher's Stone and Harry Potter, uh, are wildly different in terms of what you're looking for, if you think about it, they both begin with the word Harry, right? So in the eyes of TypeSense, in this case they are matches.

they both begin with the word hairy, right? So in the eyes of type sense, in this case they are matches. So now sometimes you have to think about, well, what do you do in the case of a tiebreaker? If Harry Potter and the Philosopher's Stone and Harry a History both have the same score? 'cause they both start with Harry, well, what is the tiebreaker? And we can have multiple tiebreakers if we want. Here's what we can do. Why don't we focus on text match,

And we can have multiple tiebreakers if we want. Here's what we can do. Why don't we focus on text match, but then in the event of a tiebreaker, let's say, hmm, what is the thing that determines whether one comes before the other? And yeah, we'll fall back to ratings count. If we want ratings count and descending order, the one that has a higher ratings count will come first, come back, reload.

that has a higher ratings count will come first, come back, reload. And now once again, we can see, okay, these all start with Harry and they have much higher ratings count than that, uh, biography, Harry a history. So of course they should come first in the results set, and this is what we want. Now in this case, notice we're getting the Kaku calling. I'm not even sure what that is. That's probably matching against, uh, one of the authors.

I'm not even sure what that is. That's probably matching against, uh, one of the authors. So if I get this, uh, out of there and we give it a reload and uh, I'm sorry, let's update this to Harry now we'll see, uh, the results that we'd probably expect. Great. So once again, if we switch back, we can reverse this and say no, let's focus on the least ratings first. All right, now we're once again going to see, uh, one of these biographies, full configurability at your fingertips.

of these biographies, full configurability at your fingertips. Let's do a little more. Uh, let's say, well, yes, focus on the text match, but maybe, hmm, maybe the release here should be factored in. Maybe you consider that more important. Uh, an ancient book that has a lot of ratings maybe, uh, for your search platform isn't as important as a more recent book.

for your search platform isn't as important as a more recent book. So in that case, we could say publicationYear in ascending order would be oldest or descending would favor the newer ones first. Okay, so now if I switch back, yep, we can see Harry Potter and the Cursed Child, um, of course was released much more recently than the original novels. So it comes higher up on the list at the top. Cool. Now keep in mind you could do a third level,

So it comes higher up on the list at the top. Cool. Now keep in mind you could do a third level, you could do a third tiebreaker or a second tiebreaker, I suppose, where you could say, okay, well after the publication year, then focus on the ratings count in descending order. So here's how you need to think about this. These are tie breakers because by default we're gonna focus on what best match the query, right?

because by default we're gonna focus on what best match the query, right? But then assuming that multiple documents have the same score based on your query, like multiple books that start with the word hairy, then we say, what is the tiebreaker? And we say, all right, the tiebreaker is going to be the publication year. But now imagine there's still a tie there, there are multiple books that start with the word hairy.

But now imagine there's still a tie there, there are multiple books that start with the word hairy that were released in the year 1998 or whatever. So now, well, what's the tiebreaker for that? If we have multiple hairy books released in hairy books released in 1998, what is the tiebreaker at that point? Well, at that point, let's say the one that has more ratings is popular. And yeah, these are, these are the sorts of things you're going to be doing in your own

And yeah, these are, these are the sorts of things you're going to be doing in your own applications, okay? But for now, let's keep it very simple and just say match on the search query, and then we will, uh, favor the ratings count. And this is fine. All right, so let's reformat this. And then the last thing I'll show you is of course, you can declare how many results you want per page. So we could say, just as an example,

you can declare how many results you want per page. So we could say, just as an example, give me only three results. And now if I reload, of course we're gonna have an array here of only three. But yeah, you can override this or stick with the defaults. Whatever you wanna do. Here we have a big list of results. Cool.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟