Laravel Scout 和 Algolia 的多语言索引 [英] Multi-language indexes with Laravel Scout and Algolia

查看:34
本文介绍了Laravel Scout 和 Algolia 的多语言索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该如何管理多语言索引(例如:page/page_translations 模型应该变成 page_en/page_fr 索引).我正在使用DimsavTranslatable"包.

How should I manage the multi-language indexes (For example: page / page_translations models should become page_en / page_fr indexes). I am using "DimsavTranslatable" package.

页面模型:id、status_id、created_at、updated_at

Page model: id, status_id, created_at, updated_at

PageTranslation 模型:id、page_id、locale、title、slug、body

PageTranslation model: id, page_id, locale, title, slug, body

Algolia 对此提供支持 (https://www.algolia.com/doc/guides/search/multilingual-search/) 但我不确定如何使用 Laravel Scout 实现这一点.

Algolia offers support for this (https://www.algolia.com/doc/guides/search/multilingual-search/) but I am not sure how to achieve this with Laravel Scout.

我想到的唯一解决方案是在存储语言环境并在搜索中应用条件的同一索引中对两个语言行(来自翻译模型)进行索引.

The only solution that comes in my mind is to index both language rows (from the translations model) in the same index storing the locale and applying a condition on search.

阿尔及利亚

objectID=1, title='英文标题', locale_id='1'

objectID=1, title='English title', locale_id='1'

objectID=2, title='Franch title', locale_id='2'

objectID=2, title='Franch title', locale_id='2'

$pages = AppPageTranslation::search('Star Trek')->where('locale_id', 1)->get();

或者也许是更好的方法?也许要分别索引 page/page_translations 并在两者中搜索?

Or maybe a better approach? Maybe to index page / page_translations separately and search in both?

我想实现以下目标:

pages_en 索引:objectID=1、title='英文标题'等

pages_en index : objectID=1, title='English title', etc.

pages_fr 索引:objectID=2、title='Franch title' 等

pages_fr index : objectID=2, title='Franch title', etc.

$pages = AppPage::search('Star Trek')->where('locale', 'en')->get();

推荐答案

我想了很多,我认为最好的方法是为每个模型使用 1 个索引并利用可以传递给 的回调::search()

I thought about it a lot and I think the best way would be to use 1 index per model and take advandate of the callback you can pass to ::search()

首先你需要使用toSearchableArray()来准备数据.我会取消所有不必要的属性(如日期),然后在其 ISO 下嵌套内容.

First you need to use toSearchableArray() to prepare the data. I would unset every unnecessary attributes (like dates) then nest content under its ISO.

{
  objectID: 1,
  en: {
    title: "Title in english",
    body: "trucated body in english"
  },
  fr: {
    title: "Titre en français",
    body: "contenu tronqué en français"
  }
}

请注意,Algolia 对每条记录的限制为 10KB.处理这个问题的最好方法是截断你最大的属性.别担心,它不会影响相关性.如果您错过了文章的后半部分,通常所有相关内容都已在前半部分.

Please note that Algolia has a limit of 10KB per records. The best way to handle this is to truncate your biggest attributes. Don't worry, it doesn't impact relevance. If you miss the second half of your article, usually all the relevant content is already in the first haft.

然后前往您的仪表板并将 fren 添加到 searchableAttributes.

Then head to your dashboard and add fr and en to the searchableAttributes.

您可以在查询时使用传递给搜索的回调来限制 searchableAttributes

You can restrict searchableAttributes at query time with a callback passed to the search

$lang = 'en';
Model::search($query, function ($algolia, $query, $options) use ($lang) {
    $options = array_merge($options, [
        'restrictSearchableAttributes' => [$lang],
    ]);

    return $algolia->search($query, $options);
});

我创建了一个特性来实现类似的目标.也许您可以做类似的事情,以获得易于使用的语法,例如:

I created a trait to achieve something similar. Maybe you can do something similar, in order to have a easy-to-use syntax like:

Model::searchLang($lang, $query);

经过深思熟虑,我真的认为这是在限制条件下使用 Laravel Scout 的最简单的方法.

After all the thinking, I really think it's the least hacky way to use Laravel Scout with your constraints.

请告诉我你的想法:)

这篇关于Laravel Scout 和 Algolia 的多语言索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆