Dynamic attributes for faceting with Laravel

Hi,

I’m using Laravel and Vue InstantSearch for my website.

I’ve created a custom admin cms for the website where the admin can create and edit the type of information collected from users when they create a profile, this information is then used in the search.

I was wonder if it was possible for “attributes for faceting” to be dynamic created from Laravel and not have to be added each time in the Algolia dashboard ?

For example if the sites admin creates a category of “music genre” with children values of “blues”, “jazz”, etc.

Could “music genre” be made a “attribute for faceting” by laravel when it is sent to algolia rather than after it’s creation in the Algolia dashboard ?

$profile[$category_parent] = $category->name;

This works when sent from the profile modal to algolia however I then need to go into the algolia dashboard to make it an “attribute for faceting”.

Maybe I’m asking for too much, however I’m curious if this is possible.

Thanks in advance for any advice.

Hi Alex,

I may have a better solution for you: You should consider Hierarchical facets - Where you can build a hierarchy in your facet values to enable multi-level navigation and filtering.

To put Hierarchical facets in your code, you may need something like this in your Profile model (pseudo-code):

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

    // ...
    $category = $this->category();

    $array['categories'] = [
        'lvl0' => $category->name, // You can also have an array here.
        'lvl1' => [],
    ];

    foreach ($category->chidrens() as $children) {
        $array['categories']['lvl1'][] = "{$category->name} > {$children->name}";
    }

    // ...

    return $array;
}

The returned $array for each profile should be something like:

"categories": {
  "lvl0": "Music",
  "lvl1": ["Music > Blues", "Music > Jazz"]
}

Side note: Since you are using Laravel Scout, you may want to consider start using Scout Extended. It’s basically Laravel Scout with Algolia specific features. Take a look at: https://github.com/algolia/scout-extended.

1 Like

Thank you so much!

Scout Extended looks great, I watched your presentation on YouTube https://www.youtube.com/watch?v=2Jy_4sL9Iug it looks like a great bridge to make working with Algolia through Laravel much easier.

I’ve followed your advice and now I’m trying to make another tree menu for my dynamic categories, however Vue InstantSearch is duplicating the first tree menu.

Do you know how to have two separate tree menus in Vue InstantSearch?

Like I mentioned I watched your presentation and a feature of Scout Extended was to have multiple models in the search.

I have a Profile model that uses data from other models.

For example Profiles have ratings which for the search is pulling in data from a Rating model.

I’m including this data through the scout method toSearchableArray()

However when the other models are updated e.g. the rating model, I have to find the corresponding profile model and update that also to keep the search up to date.

Is that something that Scout Extended addresses?

Once again thank you very much for the help.

Thanks for your words Alex.

Concerning updating the your profile search data when the rating model changes, @julienbourdeau have written this great documentation about that: algolia.com/doc/framework-integration/laravel/relationships/?language=python#updating-relations-when-parentchild-change.

Concerning the Vue InstantSearch issue - I will contact the Instasearch team to give you some feedback.

I don’t fully understand what you mean here, you can make two menus if you have two separate hierarchical attributes. Can you give the code you’re using now and how it doesn’t satisfy?

Hi Haroen,

Here’s the code for the two tree menus in Vue InstantSearch.

The first menu loads fine, however the second menu just repeats the first menu (I’ve configured everything correctly in the Algolia dashboard).

                <ais-tree-menu :attributes="[
                    'service.lvl0',
                    'service.lvl1',
                    'service.lvl2',
                    'service.lvl3',
                ]"
                :class-names="{
                    'ais-tree-menu__list': 'list-unstyled',
                    'ais-tree-menu__count': 'badge'
                  }"
                >
                <h3 slot="header">Browse by</h3>
                <hr slot="footer">
                </ais-tree-menu>

                <ais-tree-menu :attributes="[
                    'category.lvl0',
                    'category.lvl1',
                ]"
                :class-names="{
                    'ais-tree-menu__list': 'list-unstyled',
                    'ais-tree-menu__count': 'badge'
                  }"
                >
                <h3 slot="header">Categories</h3>
                <hr slot="footer">
                </ais-tree-menu>

Could you put that in a codesandbox? I haven’t seen that behaviour before @alex8 :slight_smile:

Hi Haroen,

I’m sorry but I’m not sure how I could replicate the two tree menus in Code Sandbox.

Mainly because I’m not sure of what the example data contains and whether there is two sets of separate formatted data available to use for two different tree menus.

I’ve noticed reading the Vue InstantSearch documentation that a prop for the tree menu is “attribute” which seams to be a way to “label” tree menus so that algolia / Vue know that they are separate components.

I added the attribute prop to each tree menu and this separated them allowing for each tree menu to load correctly.

                <ais-tree-menu :attributes="[
                    'service.lvl0',
                    'service.lvl1',
                    'service.lvl2',
                    'service.lvl3',
                ]"
                :class-names="{
                    'ais-tree-menu__list': 'list-unstyled',
                    'ais-tree-menu__count': 'badge'
                  }"
                  attribute="service"
                >
                <h3 slot="header">Browse by</h3>
                <hr slot="footer">
                </ais-tree-menu>

                <ais-tree-menu :attributes="[
                    'category.lvl0',
                    'category.lvl1',
                ]"
                :class-names="{
                    'ais-tree-menu__list': 'list-unstyled',
                    'ais-tree-menu__count': 'badge'
                  }"
                  attribute="category"
                >
                <h3 slot="header">Categories</h3>
                <hr slot="footer">
                </ais-tree-menu>

Hi, thanks for following up here, it seems like you discovered a bug in Vue InstantSearch v1, a reproduction is here:

This however is fixed in v2 (yay), which is currently in beta. Here’s how that would look in v2:

You can check out the migration guide: https://v2–vue-instantsearch.netlify.com/getting-started/migration.html

Does that help you?