New record viewable in Algolia index but not searchable

laravel

#1

Using Laravel 5.7x / Scout / Scout Extended, when I create a record in my application it is immediately sent to the API and appears in the index within Algolia Dashboard -> Indices. Problem is, I cannot search for this new record in my applications search tool until I run php artisan scout:import again. Until I run the import the search returns no results.

I am currently not using a queue as I am still in the testing phase.

Record in Index:

Search:
test_search_query=california

If I run scout:import, this record will then be searchable.


#2

Hi,

You have imported your data into Algolia using scout:import, but the problem is: After an $appVendor->update($data) the record is no longer searchable. Right?

Can you share the code of your model App\Vendor? Can you also share the content of the record before and after running an update?

Thanks,


#3

This isn’t an update, it is a create. I am using server side search with Scout Extended Aggregator so I can search multiple models at once. I create a record like so:

$vendor = Vendor::create([
        'vendor_no' => request('vendor_no'),
        'vendor_name' => request('vendor_name'),
        'address1' => request('address1'),
        'address2' => request('address2'),
        'city' => request('city'),
        'state_' => request('state_'),
        'zipcode' => request('zipcode'),
        'countrycode' => request('countrycode'),
        'phone_no' => request('phone_no'),
        'fax_no' => request('fax_no'),
        'email' => request('email'),
        'company_id' => session('companyID'),
    ]);

And this works, the record is immediately available in the index on the Algolia dashboard. The problem comes when I search for the record. Here is my SearchController:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Search\SearchModels;

class SearchController extends Controller
{
    public function index(Request $request)
    {

    $query = $request->input('query');

    $results = SearchModels::search($query)
                    ->with([
                        'filters' => 'company_id:'.session('companyID'),
                    ])
                    ->paginate(10);

    return view('desktop.searches.index', compact('results'));

    }
}

The newly created record will not be returned by the search even though it is available in the algolia index. But if I run scout:import again I can search for the record.


#4

Thank you. Can you share the code of your model App\Vendor file? Can you also share the content of the record on Algolia dashboard after running the create?


#5

Sure thing, one other note, search works fine on record modify.

Here is my model:

<?php

namespace App;

use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;

class Vendor extends Model
{
    use Uuids;
    
    use Searchable;

public function toSearchableArray()
{
    $array = $this->toArray();

    // Applies Scout Extended default transformations:
    $array = $this->transform($array);

    // Add extra attributes:
    $array['result_locations'] = $this->locations->map(function ($data) {
        return $data['id'];
    })->toArray();

    return $array;
}

Here is an example record in my index:


#6

This one seems hard. Let’s debug it together.

Try to search the record using a get instead of paginate and tell me if changes something.

Also, on the class Algolia\ScoutExtended\Engines\AlgoliaEngine tell the result of the variable $results on the line 84 - and also tell me the results of the line 91 return resolve(ModelsResolver::class)->from($builder, $searchable, $ids);.


#7

Created a new record and switched from paginate() to get():

the search:

test_search_query=shrute

I then modified the record in my form and searched again:

Sorry, I do not understand the second part of your question. I have verified the file and those lines are as you specified, but I am guessing that is not what you are asking for.

Thanks for your help!


#8

Just discovered something odd, the modify is creating another record in the index for the same vendor record from my table:

Also, I have noticed that the result_locations array is not populated on create, I believe this is because that step takes place after the vendor create. I tried adding a $vendor->save(); step afterwards but this did not help

$vendor = Vendor::create([
        'vendor_no' => request('vendor_no'),
        'vendor_name' => request('vendor_name'),
        'address1' => request('address1'),
        'address2' => request('address2'),
        'city' => request('city'),
        'state_' => request('state_'),
        'zipcode' => request('zipcode'),
        'countrycode' => request('countrycode'),
        'phone_no' => request('phone_no'),
        'fax_no' => request('fax_no'),
        'email_address' => request('email_address'),
        'company_id' => session('companyID'),
    ]);

    // Increment the Vendor No
    DB::table('company_next_numbers')->where('company_id', session('companyID'))- 
>increment('vendor_no');

    // Create records in location_vendor
    $vendor->locations()->attach($request->input('location_id'));

#9

Great! We are getting close.

Question: How exactly are you generating the key of the model? It seems that you are using a UUID or similar.


#10

Correct, the key is generated like so:

<?php

namespace App;

use Webpatser\Uuid\Uuid;
trait Uuids
{

     /**
     * Boot function from laravel.
     */
    protected static function boot()
    {
       parent::boot();

        static::creating(function ($model) {
            $model->{$model->getKeyName()} = Uuid::generate()->string;
        });
    }
}

and then on the model I simply do the following:

class Vendor extends Model
{
    use Uuids;

    public $incrementing = false;
}

Should I try keeping the auto-incrementing id and specify a uuid in another field for end users/routes? It will be a lot of work, but now is the time to figure it out…


#11

Tried to replicate locally your issue - installing the package Uuid and adding your code , but I everything as expected in my local machine.

IMO the problem is there is, on the code, or on your database, something transforms the uuid generated in lower case to upper case.

Good luck,


#12

I believe you are correct, I assume algolia index record match to a local database record is case-sensitive. So the initial index record that is created with lowercase uuid is useless since it was stored in the database uppercase.

I have opened a ticket on github with Webpatser. Thanks for your help solving this.


#13

Just to confirm, I modifed the trait to uppercase UUIDs by default since that is what is required for storing them in MSSQL.

mb_strtoupper(Uuid::generate()->string)

This solved my problem. I am able to search for records as soon as they are created now.