elasticsearch,nest,C#,elasticsearch,Nest" /> elasticsearch,nest,C#,elasticsearch,Nest" />

使用c#客户端嵌套的elasticsearch中的索引和全文搜索

使用c#客户端嵌套的elasticsearch中的索引和全文搜索,c#,elasticsearch,nest,C#,elasticsearch,Nest,我正在准备一个带有elasticsearch的站内搜索引擎,我是elasticsearch的新手。将使用此引擎的站点为土耳其语/英语 在土耳其,我们有像“ğ”、“ü”、“ş”、“ı”、“ö”、“ç”这样的土耳其语字母。但是当我们一般搜索时,我们使用字母“g”、“u”、“s”、“i”、“o”、“c”这不是一条规则,但我们通常会这样做,像习惯一样思考。 现在,我有一个名为“product”的文档类型,这个类型有几个字符串属性,有些是嵌套的。例如: public class Product {

我正在准备一个带有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; }
    //...
}
我的目标是:

// 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")))));
  • ProductName或Category.CategoryName可能包含土耳其语字母(“Eşarp”),或者某些可能输入错误并使用英文字母(“Esarp”)书写
  • 查询字符串可以包含土耳其语字母(eşarp),也可以不包含(esarp
  • 查询字符串可能有多个单词
  • 应根据querystring搜索每个索引字符串字段(全文搜索
现在,我做了什么:

// 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")))));
  • 在创建索引时,我还配置了映射,并使用了一个名为“sanalyze”自定义分析器,它使用“小写”和“ascifolding”过滤器和标准标记器,而不是标准分析器
  • 将该自定义分析器用于字符串字段映射
映射示例代码:

// 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")))));
//还有一些映射对所有字符串字段使用相同的映射。
.Map(m=>m.AutoMap().Properties(p=>p
.String(s=>s
.Name(n=>n.Tag).Analyzer(“sanalyze”;)))
.Settings(s=>s
.分析(ans=>ans
.分析仪(anl=>anl
.Custom(“sanalyze”,c=>c
.Tokenizer(“标准”)
.Filters(“小写”、“ascifolding”()()));
  • 我删除、重新创建并索引了我的索引
  • 现在我正试图在那个索引中搜索
我尝试使用两种不同的查询来搜索存储的文档:

q &= Query<ProductModel>.QueryString(t => t.Query(Keyword).Analyzer("sanalyze"));

q &= Query<ProductModel>.QueryString(t => t.Query(Keyword));
q&=Query.QueryString(t=>t.Query(关键字).Analyzer(“sanalyze”);
q&=Query.QueryString(t=>t.Query(关键字));
第二种方法不使用Analyzer方法,因为在elasticsearch文档中,它表示elasticsearch将使用字段上使用的分析器。因此,我认为在搜索时没有必要再次定义它

结果是什么:

// 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")))));
  • 第一次查询(使用Analyzer(“sanalyze”)): 当我搜索“eşarp”或“esarp”时,没有结果。 当我搜索“bordo”时,我得到了结果
  • 第二次查询(不带分析器(“sanalyze”)): 当我搜索“eşarp”时,我得到了结果。 当我搜索“esarp”时,没有结果。 当我搜索“bordo”时,我得到了结果
顺便说一句:

  • 文档包含“Eşarp”作为产品名称值,当我选中elasticsearch创建时,“esarp”字段术语

  • 文档包含“Bordo”作为值和“Bordo”作为字段项

我无法得到我想要的。我做错了什么? -我应该使用另一个过滤器而不是AsciFolding吗? -我应该将preserveOriginal与asciifolding一起使用吗?我不想用这个选项来不得分。 -有什么不同的事情要做吗

你能帮帮我吗

如果你认为我问的问题不清楚,请告诉我,我会尽量说清楚


谢谢。

使用
query\u string
的默认设置意味着您正在
\u all
字段中搜索。
\u all
字段有自己的分析器-标准的
分析器

您需要指定要对哪个字段执行操作的
query\u string

  "query": {
    "query_string": {
      "query": "your_field_name:esarp"
    }
  }


@Russcapm,这是我的新问题:-)如果你能帮助我,我将非常感激。看起来你有一个编码问题。Ascii编码删除不可打印的字符。因此,只能得到字符0-127,而不是128-255,这是非标准阿拉伯语字符所在的位置。我不确定您的文本是否也可能包含unicode字符。我在使用ToString()方法时也遇到过同样的问题,该方法也使用Ascii编码。@jdweng但有一件事让我感到困惑。当一个属性有“Eşarp”这样的值时,我会检查并验证“esarp”是否被创建为一个术语/令牌。按照我的逻辑,sanalyze alanyzer可以很好地索引。搜索时,我想我需要使用一些东西(我不知道该怎么做)来处理querystring,就像sanalyze analyzer在索引时对字符串字段所做的那样,然后用索引项搜索分析过的querystring。我错了吗?比如,如果“eşarp”被编入索引并保存为“esarp”一词,那么如果我使用“eşarp”作为查询字符串,如果它可以像“esarp”一样搜索,那么应该没有问题?任何字符串搜索方法都应该可以。过滤正在导致问题。我不懂土耳其语,但我见过许多不同语言的奇怪问题。某些语言的字符有多个大写/小写。ascifolding将忽略某些字符,因此它在某些情况下有效,而在其他情况下无效。您可能需要创建自己的大写/小写方法来解决此问题。我不会使用asciiFolding。@zokkan-这可能会帮助您-Hi@Andrei我可以为映射中的_all字段指定analyzer吗?因为我需要搜索很多属性,其中一些位于嵌套属性中。老实说,我不知道如何进行全文搜索,包括文档的字符串属性和嵌套属性。如果可以,请举例说明。我明天会试试,现在是晚上10点:-)@zokkan,是的,您可以使用类型映射描述符上的
.AllField(a=>a.analyzer(“折叠分析器”)
\u all
字段指定分析器。看,嗨,安德烈,我有很多