使用 c# client Nest 在没有 dialitics 的情况下在 elasticsearch 中进行索引和全文搜索
indexing and full text searching in elasticsearch without dialitics using c# client Nest
我正在准备一个带有 elasticsearch 的站内搜索引擎,我是 elasticsearch 的新手。将使用此引擎的站点是 土耳其语/英语。
在土耳其,我们有土耳其语字母,例如 'ğ'、'ü'、'ş'、'ı'、'ö'、'ç'。但是我们在搜索的时候一般会使用字母'g','u','s','i','o','c'。 这不是规定,但我们通常会这样做,像习惯一样思考,我们习惯了。
现在,我有一个名为 "product" 的文档类型,这个类型有几个字符串属性,有些是嵌套的。例如:
public class Product {
public string ProductName { get; set; }
public Category Category { get; set; }
//...
}
public class Category {
public string CategoryName { get; set; }
//...
}
我的目标是:
- ProductName 或 Category.CategoryName 可能包含土耳其字母 ("Eşarp"),或者某些可能被打错并用英文字母书写 ("Esarp")
- 查询字符串可能包含土耳其字母 ("eşarp") 或不包含 ("esarp")
- 查询字符串可能有多个词
- 应根据查询字符串搜索每个索引字符串字段(全文搜索)
现在,我做了什么:
- 在创建索引时,我还配置了映射并使用了一个名为 "sanalyze" 的 自定义分析器,它使用“小写字母”和“asciifolding”过滤器和标准分词器而不是标准分析器。
- 将自定义分析器用于字符串字段映射。
映射示例代码:
// some more mappings which uses the same mapping for all string fields.
.Map<Yaziylabir.Extensions.TagManagement.Models.TagModel>(m => m.AutoMap().Properties(p => p
.String(s => s
.Name(n => n.Tag).Analyzer("sanalyze")))))
.Settings(s => s
.Analysis(ans => ans
.Analyzers(anl => anl
.Custom("sanalyze", c => c
.Tokenizer("standard")
.Filters("lowercase", "asciifolding")))));
- 我删除、重新创建并索引了我的索引
- 现在我正在尝试在该索引中进行搜索。
我尝试使用两个不同的查询来搜索存储的文档:
q &= Query<ProductModel>.QueryString(t => t.Query(Keyword).Analyzer("sanalyze"));
q &= Query<ProductModel>.QueryString(t => t.Query(Keyword));
第二个不使用Analyzer 方法,因为在elasticsearch 文档中,它说elasticsearch 将使用字段上使用的分析器。所以我觉得搜索的时候没必要再定义。
我得到的结果:
- 第一次查询(使用分析器("sanalyze")):
当我搜索 "eşarp" 或 "esarp" 时,没有结果。
当我搜索 "bordo" 时,我得到了结果。
- 第二次查询(没有分析器("sanalyze")):
当我搜索 "eşarp" 时,我得到了结果。
当我搜索 "esarp" 时,没有结果。
当我搜索 "bordo" 时,我得到了结果。
顺便说一句:
文档包含“Eşarp”作为 ProductName 值,当我检查 elasticsearch 时创建了“esarp”字段术语。
文档包含“Bordo”作为值和“bordo”作为字段项。
我无法实现我想要的。我做错了什么?
- 我应该使用另一个过滤器而不是 asciifolding 吗?
- 我应该将 preserveOriginal 与 asciifolding 一起使用吗?我不想使用该选项来避免得分。
- 有什么不同的事情要做?
你能帮帮我吗?
如果你觉得我问的不清楚,请告诉我,我会尽量说清楚。
谢谢。
使用 query_string
的默认设置意味着您在 _all
字段中搜索。 _all
字段有自己的分析器 - standard
一个。
您需要指定希望query_string
作用于哪个字段:
"query": {
"query_string": {
"query": "your_field_name:esarp"
}
}
或
"query": {
"query_string": {
"query": "esarp",
"default_field": "your_field_name"
}
}
我正在准备一个带有 elasticsearch 的站内搜索引擎,我是 elasticsearch 的新手。将使用此引擎的站点是 土耳其语/英语。
在土耳其,我们有土耳其语字母,例如 'ğ'、'ü'、'ş'、'ı'、'ö'、'ç'。但是我们在搜索的时候一般会使用字母'g','u','s','i','o','c'。 这不是规定,但我们通常会这样做,像习惯一样思考,我们习惯了。
现在,我有一个名为 "product" 的文档类型,这个类型有几个字符串属性,有些是嵌套的。例如:
public class Product {
public string ProductName { get; set; }
public Category Category { get; set; }
//...
}
public class Category {
public string CategoryName { get; set; }
//...
}
我的目标是:
- ProductName 或 Category.CategoryName 可能包含土耳其字母 ("Eşarp"),或者某些可能被打错并用英文字母书写 ("Esarp")
- 查询字符串可能包含土耳其字母 ("eşarp") 或不包含 ("esarp")
- 查询字符串可能有多个词
- 应根据查询字符串搜索每个索引字符串字段(全文搜索)
现在,我做了什么:
- 在创建索引时,我还配置了映射并使用了一个名为 "sanalyze" 的 自定义分析器,它使用“小写字母”和“asciifolding”过滤器和标准分词器而不是标准分析器。
- 将自定义分析器用于字符串字段映射。
映射示例代码:
// some more mappings which uses the same mapping for all string fields.
.Map<Yaziylabir.Extensions.TagManagement.Models.TagModel>(m => m.AutoMap().Properties(p => p
.String(s => s
.Name(n => n.Tag).Analyzer("sanalyze")))))
.Settings(s => s
.Analysis(ans => ans
.Analyzers(anl => anl
.Custom("sanalyze", c => c
.Tokenizer("standard")
.Filters("lowercase", "asciifolding")))));
- 我删除、重新创建并索引了我的索引
- 现在我正在尝试在该索引中进行搜索。
我尝试使用两个不同的查询来搜索存储的文档:
q &= Query<ProductModel>.QueryString(t => t.Query(Keyword).Analyzer("sanalyze"));
q &= Query<ProductModel>.QueryString(t => t.Query(Keyword));
第二个不使用Analyzer 方法,因为在elasticsearch 文档中,它说elasticsearch 将使用字段上使用的分析器。所以我觉得搜索的时候没必要再定义。
我得到的结果:
- 第一次查询(使用分析器("sanalyze")): 当我搜索 "eşarp" 或 "esarp" 时,没有结果。 当我搜索 "bordo" 时,我得到了结果。
- 第二次查询(没有分析器("sanalyze")): 当我搜索 "eşarp" 时,我得到了结果。 当我搜索 "esarp" 时,没有结果。 当我搜索 "bordo" 时,我得到了结果。
顺便说一句:
文档包含“Eşarp”作为 ProductName 值,当我检查 elasticsearch 时创建了“esarp”字段术语。
文档包含“Bordo”作为值和“bordo”作为字段项。
我无法实现我想要的。我做错了什么? - 我应该使用另一个过滤器而不是 asciifolding 吗? - 我应该将 preserveOriginal 与 asciifolding 一起使用吗?我不想使用该选项来避免得分。 - 有什么不同的事情要做?
你能帮帮我吗?
如果你觉得我问的不清楚,请告诉我,我会尽量说清楚。
谢谢。
使用 query_string
的默认设置意味着您在 _all
字段中搜索。 _all
字段有自己的分析器 - standard
一个。
您需要指定希望query_string
作用于哪个字段:
"query": {
"query_string": {
"query": "your_field_name:esarp"
}
}
或
"query": {
"query_string": {
"query": "esarp",
"default_field": "your_field_name"
}
}