【问题标题】:I18n search and filtering in ElasticsearchElasticsearch 中的 I18n 搜索和过滤
【发布时间】:2015-12-01 13:46:06
【问题描述】:

tldr;

如何使用本地化索引匹配和过滤本地化搜索?

长版

我有一个应用程序,用户搜索必须在其语言的上下文中完成。

在弹性搜索索引中,我想要同时具有 i18n 属性和非 i18n 属性的文档(我想避免创建多个索引,每种语言一个索引)。

文档的映射应如下所示:

'entry': {
'properties': {
  'name' : {'type': 'string'}, /* unlocalized properties */
  'category': { /* localized properties */
      "properties" : {
          "lang_fr" : {
              "type" : "string"
          },
          "lang_de" : {
              "type" : "string"
          }
      }
  },}}

有了这个,我有两个要求:

1) 匹配:在进行搜索时,将与用户语言无关的本地化字段排除在搜索之外(假设用户的语言是'fr',我想排除'de ' 来自搜索的字段。如何在不指定要搜索的整个字段列表的情况下执行此操作。首先,我尝试了这个,但它不起作用:

{
  "query": {
    "match": {
      "*.lang_fr": "full_text"
    }
  }
}

但是,"categories.lang_fr": "full_text" 运行良好。但我不想维护查询中的字段列表。我想要一个像 SolR 一样的通用规则。

2) 过滤:当我检索我的结果时,我想过滤掉所有与我的用户语言不对应的本地化字段。换句话说,使用 source 过滤器,我想要所有未本地化的字段,排除所有以 "lang" 开头的字段,但包括所有字段为 'lang_fr'。我尝试了以下方法,但它不起作用:

{
"_source": {
    "include": [ "*", "*.lang_fr" ],
    "exclude": [ "*.lang_*" ],
}
...}

通配符运算符似乎不起作用。如果我指定"categories.lang_de",我部分拥有我想要的东西,但同样,我不想维护字段列表,我想要一个通用规则。包含/排除操作无法按我的意愿工作。唯一真正有效的是一个查询,我在其中指定要排除所有字段的所有语言,例如:

{
"_source": {
    "exclude": [ "categories.lang_de", "categories.lang_en",  "categories.lang_it", 
                         "another_field.lang_de", "catanother_fieldgories.lang_en",  "another_field.lang_it"],
}
...}

用于“fr”搜索。

我很惊讶在谷歌上找不到任何东西。我将其视为 i18n 应用于 elasticsearch 的一个非常标准的案例。也许我在 ES 中以错误的方式对 i18n 建模?

提前谢谢你!

【问题讨论】:

    标签: search elasticsearch internationalization


    【解决方案1】:

    您可以使用query_string query 实现第一个,它利用强大的Lucene 表达式语言并允许指定wildcard in field names

    {
      "query": {
        "query_string": {
          "query": "\\*.lang_fr:full_text"
        }
      }
    }
    

    或者也可以在fields参数中指定字段名,像这样

    {
      "query": {
        "query_string": {
          "query": "full_text"
          "fields": ["*.lang_fr"]
        }
      }
    }
    

    至于第二个,源过滤确实是要走的路,但我建议简单地排除所有语言,但要搜索的语言除外。例如,如果搜索是法语,您只需排除所有其他语言,而不必列举所有字段,只需列举您不想要的所有语言(这会少得多)。这将允许您随时添加本地化字段,而无需更改查询。

    {
    "_source": {
        "exclude": [ "*.lang_de", "*.lang_it" ],
    }
    ...}
    

    【讨论】:

      猜你喜欢
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 2016-10-26
      • 2014-09-08
      • 1970-01-01
      • 2012-08-30
      • 2019-04-25
      相关资源
      最近更新 更多