laravel/scout

Typesense: Search throws exception -> fields is required

saibotk opened this issue · 5 comments

Scout Version

10.8.1

Scout Driver

Typesense

Laravel Version

10.35.0

PHP Version

8.3.2

Database Driver & Version

Typesense 0.25.2

SDK Version

Typesense PHP 4.9.1

Meilisearch CLI Version

No response

Description

When following the documentation about adding the new Typesense driver, just calling search on a User model fails.
I followed the documentation and added the toSearchableArray() function.
It seems like Typesense then tries to create the collection schema, because it did not exist yet? And fails.

This line throws the exception later:

$this->typesense->getCollections()->create($schema);

Telling me that it is missing the fields parameter. This is because in the code above it only sends the name of the schema without fields, when no schema is found in the config.
If this is wrongly documented and a schema definition is necessary in the config file, then

  1. This should be configurable via some array or interface on the model instead of keeping per model schema definitions in the config
  2. This should then throw an error instead of trying to make a request, as it seems like code-wise this is an expected use-case (no exception thrown in the engine code)

Steps To Reproduce

  1. Clean Laravel project with Scout and Typesense setup
  2. Go to the user model and add the toSearchableArray definition and the Searchable trait.
  3. Do not change any config in the scout config.
  4. Call User::search("test")->get()

@saibotk In addition to defining toSearchableArray you'd also need to specify the schema in the Scout config.

This is described under this section in the docs (the 2nd code block in that section), but I just realized that the way it's written makes it sound like you'd only need to add that section if you use soft deletes, which is not the case.

Will fix that shortly in the docs.

Thanks for the quick answer!

I thought so, but it is still not very elegant to do so.

A more native approach would be to get those fields from the model as we also do with for example the searchable fields.
Or is there something preventing us from implementing this?

Also maybe something missing in the docs:
What happens if we change the config later on, is that okay or do we need to add a warning to the documentation, because maybe Typesense cannot change / migrate the schema definition on its own?

Oh and additionally we might then want to throw an exception instead of trying to execute the create function i linked above without any fields.

A more native approach would be to get those fields from the model as we also do with for example the searchable fields.
Or is there something preventing us from implementing this?

Typesense also requires additional schema settings like data types, whether a field should be optional or not, locale, etc.

Given that this is Typesense-specific and also because every engine might have it's own set of unique settings, this is implemented in config/scout.php instead of in the model. Or at least that's my observation...

But I'll let @driesvints or @taylorotwell chime in on this.

I've opened a PR here to clarify the docs: laravel/docs#9280

What happens if we change the config later on, is that okay or do we need to add a warning to the documentation, because maybe Typesense cannot change / migrate the schema definition on its own?

I've clarified this as well in that PR.

Oh and additionally we might then want to throw an exception instead of trying to execute the create function i linked above without any fields.

We let Typesense handle any schema validations server-side, to avoid having to repeat the same logic in each client.

I think as long as we document things clearly, doing it in the config file is fine.