algolia / scout-extended

Scout Extended: The Full Power of Algolia in Laravel
https://www.algolia.com/doc/framework-integration/laravel/getting-started/introduction-to-scout-extended/
MIT License
399 stars 84 forks source link

Aggregator returns full model #224

Open seivad opened 4 years ago

seivad commented 4 years ago

It seems like the Aggregator returns the full model even though at Algolia's end, the indices look correct.

For example at Algolias end within an aggregated indices:

{
  "id": 60,
  "quote_id": 20,
  "product_id": null,
  "approved": true,
  "details": "U2 GRD 2.0047686",
  "construction_stage": "pergola / decking / landscape",
  "item": "laboriosam sint temporibus magni explicabo laudantium",
  "lm": 794062,
  "eqa": 6400,
  "approved_at": 1582486726,
  "created_at": 1582590124,
  "quote": {
    "id": 20,
    "company_id": 2,
    "quotable_id": 7,
    "quotable_type": "job"
  },
  "_tags": [
    "Universal\\Model\\QuoteItem::60"
  ],
  "objectID": "Universal\\Model\\QuoteItem::60"
}

but what gets returned when searching in my Laravel app is:

id: 60
quote_id: 20
shop_id: null
product_id: null
assigned_to: null
parent_id: null
preferred_supplier: null
cbs_product_id: null
approved: true
delivery: 1
lost: false
cut_build_delivery_same_day: false
details: "U2 GRD 2.0047686"
product_type: null
construction_stage: "pergola / decking / landscape"
item: "laboriosam sint temporibus magni explicabo laudantium"
lm: "794062.00"
eqa: "6400.00"
delivery_price: null
ancillaries_price: null
price: 358900
order_price: 367300
unit_type: "eqa"
units: 3
width: null
depth: null
length: null
comments: "Dolor id voluptas ea veniam molestiae nihil cupiditate."
options: [{label: "Treated", component: "dynamic-checkbox", options: [], value: false, values: [],…}]
ezequote_values: null
ancillaries: null
lost_reason: "Est ducimus expedita recusandae consequuntur sed."
lost_comments: "Qui et ad itaque voluptatem. Nobis debitis sunt recusandae sunt rem. Non quas itaque deleniti adipisci dolores et.↵↵Praesentium vitae aliquam minima cumque quas odit aut. Repellendus sequi laudantium quia hic iusto. Pariatur est sit cupiditate culpa natus."
lost_to: "Sawayn Group"
approved_at: "23-02-2020"
milestone_detail_date: "2020-02-14 00:00:00"
approx_del_date: "10-02-2020"
lost_at: "2020-01-30 07:22:41"
created_at: "2020-02-25 00:22:04"
updated_at: "2020-02-25 00:22:04"
deleted_at: null
class_name: "QuoteItem"
quote: {id: 20, company_id: 2, created_by: 46, quotable_type: "job", quotable_id: 7, delivery: 0,…}
id: 20
company_id: 2
created_by: 46
quotable_type: "job"
quotable_id: 7
delivery: 0
type: "New Home"
construction_stage: "general hardware"
number: "5062-13"
status: "rejected"
delivery_price: null
required_by: "2020-02-09 00:00:00"
issued: "2020-02-16 00:00:00"
delivery_docket: "2020-02-01 13:37:23"
picking_slip: "2020-02-08 20:51:26"
created_at: "2020-02-25 00:22:04"
updated_at: "2020-02-25 00:22:04"
deleted_at: null
group: null
subtotal: 1352100
gst: 135210
total: 1487310
job: {id: 7, project_id: 4, primary_contact_id: 30, original_job_id: null, active: true, quoting_stage: 0,…}
items: [{id: 58, quote_id: 20, shop_id: null, product_id: null, assigned_to: null, parent_id: null,…},…]
groups: []

my Aggregator for global search looks like:

class GlobalSearch extends Aggregator
{
    /**
     * The names of the models that should be aggregated.
     *
     * @var string[]
     */
    protected $models = [
        User::class,
        Staff::class,
        Company::class,
        Customer::class,
        Contact::class,
        Quote::class,
        QuoteItem::class,
        Project::class,
        Job::class,
        Component::class,
    ];

    /**
     * Map of model relations to load.
     *
     * @var string[]
     */
    protected $relations = [
        QuoteItem::class => ['quote.job'],
    ];

    /**
     * @return mixed
     */
    public function shouldBeSearchable()
    {
        // Check if the class uses the Searchable trait before calling shouldBeSearchable
        if (array_key_exists(Searchable::class, class_uses($this->model))) {
            return $this->model->shouldBeSearchable();
        }
    }
}

and all of the models are returning the full results but for instance the QuoteItem Model has this:

    /**
     * @return mixed
     */
    public function toSearchableArray()
    {
        $array = $this->only([
            'id',
            'quote_id',
            'product_id',
            'approved',
            'details',
            'construction_stage',
            'item',
            'lm',
            'eqa',
            'approved_at',
            'created_at',
        ]);

        $array['quote'] = [
            'id' => $this->quote->id,
            'company_id' => $this->quote->company_id,
            'quotable_id' => $this->quote->quotable_id,
            'quotable_type' => $this->quote->quotable_type,
        ];

        // $array = $this->transform($array);

        return $array;
    }

Which is what I expect to come back. I've commented out transform, no difference. My search controller looks like this:

class SearchController extends Controller
{
    /**
     * @return mixed
     */
    public function index()
    {
        $results = GlobalSearch::search(request()->get('query'))->get()->map(function ($d) {
            $className = class_basename(get_class($d));
            $d->class_name = $className;

            return $d;
        });

        return response()->json([
            'results' => $results,
        ], Response::HTTP_OK);
    }
}

I have no idea why it looks correct on Algolia's store but the results coming back at the full model. Obviously I want the payload to be as small as possible, so there is no need for timestamps and unnecessary fields etc... Hopefully someone can shed some light on why this is happening and how to resolve to just the results at Algolia's end.

seivad commented 4 years ago

Sorry I've just noticed that I return just ->raw() I get the algolia model which is what I am after and not the entire object from the database. I might have to stick with that for the time being instead of mapping over each result type in the aggregator and slimming the response down.