teamtnt / laravel-scout-tntsearch-driver

Driver for Laravel Scout search package based on https://github.com/teamtnt/tntsearch
MIT License
1.1k stars 144 forks source link

Index entire model while still filtering result fields/columns. #108

Closed humblecoder closed 7 years ago

humblecoder commented 7 years ago

It's quite possible I'm missing something very simple and straightforward, but is there any way to index all fields for search, but filter the results dynamically as needed? For example, say I have a PERSON model, and I want to index all fields:

Person.first_name Person.last_name Person.height Person.weight

However, in some searches, I only wish to see Person.first_name Person.last_name

In a "normal" scenario, I could say:

Person::all()->get(['first_name','last_name'])

However, it doesn't appear that the following behaves the same way:

TNTSEARCHMODEL::search()->get(['first_name','last_name'])

It always returns all fields. Is there an efficient mechanism to work around this? It seems that this may be a limitation of Scout itself, but I thought I'd ask to verify.

FYI, so far the only things I can come up with would be to: 1) pluck the IDs and re-search locally (but that's rather counterintuitive) 2) "Map" through and filter the results manually Best

dominiquedutra commented 7 years ago

@humblecoder Isnt Model::search() supposed to be used to fetch the IDs first, and only then you do the real search? I believe that's the recommended way and you may run into some issues. Thats what I do. When you do a Model::search() you are searching the Index (tntsearch / sqlite) anyway. You will always have two separated queries.

This is roughly what I have:

Cars::whereIn(
    'id',
    collect(Cars::search('Toyota -camry')->raw()['ids'])->flatten()->all()
)->get(['id', 'make', 'year', 'model']);

Hope it helps,

humblecoder commented 7 years ago

Actually I "solved" it with a simple ->makeHidden(['created_at','deleted_at','updated_at','relevance']); call for the fields I didn't want to see. Not quite the same, but it works -- and only a "single" call.