Elastic Json Table
I'm trying solve a complicated problem and I'm looking for suggestions. I have an elastic index with 11.72 million docs I want to represent in a table. I created this index using fscrawler. It represents a single source of truth. However, filament tables are not really meant to handle this type. I've jumped a few hurdles using this post https://filamentphp.com/blog/how-to-consume-an-external-api-with-filament-tables. However, I need to filter that data by multiple searches and elastic can only query 10,000 records which you could increase, but it isn't 11 million. I think the path would be to create independent inputs per "column" and filter the data. So imagine a widget that feeds the table a query. Any questions or suggestions just looking for guidance.
42 Replies
So imagine a widget that feeds the table a query.What would this look like? A form above the table so you can pre-fill some filters before the initial table query runs?
As above, I would recommend a filter form above ideally
@pboivin yes, that's how I had imagained it. Not sure how to do that, but seems logical.
I think it should be pretty straightforward, are you on a resource listing or a custom page?
That's a simple resource now.
Cool, let's see if I have something similar in my current project
Sort of...
I think the first step would be to create your Widget. Have you ever used the Forms package outside of the admin?
can't say that I have. It's all pretty new to me on the TALL side.
Ok, no worries. Start by creating your Widget, and add it to
getHeaderWidgets()
in your simple resource.
The Widget itself is a Livewire component, so you can pick up the Forms docs here :
https://filamentphp.com/docs/2.x/forms/getting-started#preparing-your-livewire-component
You can define your custom form there and then, the hard part will be connecting it to the Page component, to interact with the table 😄gives me a jumping off point thanks
Cool! Let me know when you're there, I'll help you with the table stuff (if I can...)
So we have an input box now. In order to load results we're calling a method on the model getRows(). How can I wire those two things up?
Oh, I forgot you are using Sushi... not sure if it'll make a difference
Are you handling a
submit
event on the form?
Something like this on the widget class
You can then catch this event in the Page component and dynamically update the table queryI prolly need to learn how to catch that event ha
Livewire
Events | Livewire
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
This has been super helpful. I wasn't able to get emitUp to work, but emit does. Probably cause my listener is still on the component. Edit: moved it and emitUp works fine.
expects builder hmm..
Yeah so this might be a bit more complicated with Sushi, but let's see...
Something like this should work with a regular model:
I like idea, but keep in mind we can only X amount of rows from the elastic API. I need to hit that getRows($query) function for a fresh call.
Yeah, that's the main issue, you want to pass the parameter to the Sushi, not modify the eloquent query
There is no database involved at all here.
I think I have something from a couple of months ago... 2 sec
getRows returns correct data, but doesn't refresh table.
I don't have a ton of experience with Sushi, so there may be a better way. But this how I'm passing parameters to my Sushi model currently:
Maybe something like this for your use case:
In your event listener, save the search value to a public property instead ^
Then the table will refresh automatically if you setup
getTableQuery()
Okay, that should be helpful. How does getRows get called here though? Asking from ignorance
It gets called behind the scenes, you don't usually have to call it yourself. The sushi model acts like a regular model, so the filament table will build the query from what it finds in
getTableQuery()
very close.
if I dump
static::$original_search
it has the value, but seems to fail right at the static::query()
part.
wehen I dump static::query() it's just an instance for Builder for the originals model.
Yes that's normal
So the table will get the Builder instance and prepare the final query. Then behind the scenes, Sushi will hit the
getRows()
method which is what it uses instead of a DB table.It seems to never do that last step
What do you have in
getTableQuery()
?
the whole widget
Ah ok, do the listener is the issue I think
1 sec
Whoa, wait. This is all in the widget?
Do you have anything on the Page component?
This is what I have in mind for the widget:
Okay, I can move the rest to ManageOriginals
I think for Manage... :
Today has been a lesson.
For sure! Covered a lot of ground with this feature 😄
Yeah you're kind of awesome, but if anybody asks I'll deny it.
I'll take the compliment for now 👌
@pboivin what do you think the best approach to having multiple search boxes?
aka table filtering ha
You can bind the entire form to a single property (array), so if you have multiple fieds, you can still emit just the single array to the page component and pass it along to the Sushi model
https://filamentphp.com/docs/2.x/forms/getting-started#scoping-form-data-to-an-array-property
Been following this today. Really impressive.
@pboivin legit I have learned more today than I have in a crazy long time. Thank you so much for taking the time out. I owe you a cold 🍺 or 10.