Aggregate models with Laravel, VueInstantSearch, Spatie Laravel-MediaLibrary into one index

Have a interesting problem. In the laravel app there are two models Job.php and Media.php. Media is attached to the Job via Spatie’s Laravel-MediaLibrary package. After making job and media models searchable with toSearchableArray() they make their way to Algolia.

Presenting the results is happening via VueInstantSearch. If this were only handled on the server this line would call the media:

// php controller
...prep code
$imageUrl = $job->getMedia('document')->first()->getUrl('thumbnail');

However, with algolia the controller is not fetching the job, so that code relationship is gone and useless for calling the job media path. I feel like I’m on the right track here:

// Vue.component
<img src=“'/storage/'+ item.model_id + '/conversions/' + item.file_name” width=200 height=120  />

I tried using the aggregator: https://www.algolia.com/doc/framework-integration/laravel/advanced-use-cases/multiple-models-in-one-index/?language=php#aggregators---multiple-models-in-one-index

but this seems only for server, backend type search scenarios. I found this gist, but I’m not sure the relationship would be held (between Job and Media) that my search requires.

Do you have any ideas of how to accomplish this?

Thank you,

Trevor

Hi @BidBird!
Just to confirm – the end goal is to have both Jobs and Media information searchable together from one UI, right? What is the relationship between these models? It appears each job record will have media information on it, correct? Is the end goal then to search for jobs via some of the media information for each job? (In addition to other attributes on the job model)

If so, I would recommend using the aggregator you linked to index that information correctly. In that case, you could do a simple single index search with Vue IS on the front-end.

Let us know if you think that won’t work or if I’ve misunderstood what you’re trying to do!

Yey, @maria.schreiber you’re so helpful.

Well, here’s the thing. There’s a relationship between the media_id and the job_id. So, at least on the php side if you make the job available that getMedia() method has some backend code which retrieves it.

However, I looked through the indices for the VueIS and it appears a name say the indexName: ‘jobs’, and then there’s a second call for indexName: ‘media’. My concern is that approach does not have them coupled, or relating immediately to each other. (could be wrong here)

It appears each job record will have media information on it, correct? Is the end goal then to search for jobs via some of the media information for each job?

Actually, the “media” is just a fancy name in the package for ‘thumbnail’ image. So, this is basically a thumbnail for a job post. I thought the aggregator would help, but when a job is created it’s not sending both model attributes to the same job index.

Is that possible with Vue Instant search?

Ah, thanks for the clarifications! While it might be possible to do this using Vue, we generally recommend getting the data model right in the back-end, and then using our IS libraries just for front-end. In other words, we hope you have to do as little computation as possible using Vue. This makes writing the front-end simpler and also makes it more performant as you’ll only need to make one query rather than two.

If I understood correctly, the media table has thumbnail urls and their id should match (or have some other straightforward relationship) with the job that the thumbnail belongs to. Indeed, if that’s the case, the aggregator does not fit it, since it combines records from two models into one index but does not actually combine them into each record in the index. (So there would be separate job records and thumbnail records, but no records with information from both.)

I would recommend accessing the API directly and writing a short script that sends partialUpdates to the Jobs index to add on the appropriate thumbnail onto each job record. This way, you can simply grab the thumbnail right off the returned job result. Does that sound like a plausible approach?

Alternatively, could you join the tables beforehand on job_id = media_id and then index this joined table?

ok, let me give that a try this weekend…

I think the media table has the job_id. Maybe there’s a query I can do against that in vue…to compare item.job_id with media_id and job_id.

Thank you ~

Trevor

I am facing login Laravel Forge issue, guide me please

Hi @zackyseo, are you experiencing an Algolia library/extension related issue? If so, could you please expand on the issue and we would be happy to try and provide guidance.