C# Nest/Elasticsearch - 创建索引但分析不起作用

问题描述

我是 ElasticSearch 和 nesT 的新手,遇到了一个问题。

我正在尝试添加分析器和标记器,以便我可以在代码搜索子字符串。

示例:

User user1 = new User(){ FirstName = "John",LastName = "Boat",Number="45678" }
User user2 = new User(){ FirstName = "Michael",LastName = "Johansen",Number="123456" }

搜索“12345”得到 user2,“456”得到 user1 & user2,“Joh”得到 user1 & user2,等等

但是,在创建索引时尝试将分析器和令牌过滤器添加到我的设置中时,它们并没有保存在弹性数据库中。

这有效:

client.Indices.Create("customers",index => index
                .Settings(se => se
                        .Setting("index.mapping.total_fields.limit","2000"))
                .Map<Customer>(x => x.AutoMap())
            );

这不起作用:

client.Indices.Create("crmleads",index => index
                .Settings(se => se
                    .Analysis(a => a
                        .Analyzers(analyzer => analyzer
                            .Custom("substring_analyzer",analyzerDescriptor => analyzerDescriptor
                                .Tokenizer("standard")
                                .Filters("lowercase","substring")))
                        .TokenFilters(tf => tf
                            .NGram("substring",filterDescriptor => filterDescriptor
                                .MinGram(2)
                                .MaxGram(15))))
                    .Setting("index.mapping.total_fields.limit","2000"))
                .Map<Crmlead>(x => x
                    .AutoMap()
                    .Properties(p => p
                        .Text(t => t
                            .Name(f => f.Name)
                            .Analyzer("substring_analyzer"))
                        .Text(t => t
                            .Name(f => f.CVRNumber)
                            .Analyzer("substring_analyzer"))
                        .Boolean(t => t
                            .Name(f => f.IsConverted))
                        .Text(t => t
                            .Name(f => f.ContactPersonName)
                            .Analyzer("substring_analyzer"))
                        .Text(t => t
                            .Name(f => f.ContactPersonEmail
                            ).Analyzer("substring_analyzer"))))
            );

ElasticSearch 服务器的命令行也没有显示任何错误

Command line for ElasticSearch

Created indexes shown in Kibana

此外,我还没有向模型类添加任何内容

public class Crmlead
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Guid Id { get; set; }
        public Company Company { get; set; }
        public Customer Customer { get; set; }
        public string CVRNumber { get; set; }
        public DateTime CreateDate { get; set; }
        public string Name { get; set; }
        public string Website { get; set; }
        public string Country { get; set; }
        public string Address { get; set; }
        public string ZipCode { get; set; }
        public string City { get; set; }
        public string ContactPersonName { get; set; }
        public string ContactPersonEmail { get; set; }
        public string ContactPersonPhoneNumber { get; set; }
        public string PhaSEOneDescription { get; set; }
        public CustomerContact CustomerContact { get; set; }
        public ApplicationUser Seller { get; set; }
        public CrmleadStatus CRMStatus { get; set; }
        public List<UploadedFile> UploadedFiles { get; set; }
        public bool IsConverted { get; set; }
        public bool IsDone { get; set; }
        public bool IsSold { get; set; }
    }

完整代码在这里

public static void AddElasticsearch(this IServiceCollection services,IConfiguration configuration)
        {
            var url = configuration["Elasticsearch:url"];

            var settings = new ConnectionSettings(new Uri(url));

            AddDefaultMappings(settings);

            settings.DefaultFieldNameInferrer(f => f);

            var client = new Elasticclient(settings);

            services.AddSingleton<IElasticclient>(client);

            CreateIndices(client);

        }

private static void AddDefaultMappings(ConnectionSettings settings)
        {
            settings
                .DefaultMappingFor<ApplicationUser>(m => m
                    .IndexName("users")
                    .Ignore(au => au.AccessFailedCount)
                    .Ignore(au => au.Address)
                    .Ignore(au => au.AppInstalled)
                    .Ignore(au => au.BirthDay)
                    .Ignore(au => au.BorrowedEquipment)
                    .Ignore(au => au.ConcurrencyStamp)
                    .Ignore(au => au.CostPrice)
                    .Ignore(au => au.Culture)
                    .Ignore(au => au.CustomUserfields)
                    .Ignore(au => au.EmailConfirmed)
                    .Ignore(au => au.HireDate)
                    .Ignore(au => au.IceRelatives)
                    .Ignore(au => au.Id)
                    .Ignore(au => au.Initials)
                    .Ignore(au => au.IsCompanyOwner)
                    .Ignore(au => au.LastLogin)
                    .Ignore(au => au.LockoutEnabled)
                    .Ignore(au => au.LockoutEnd)
                    .Ignore(au => au.normalizedEmail)
                    .Ignore(au => au.normalizedUserName)
                    .Ignore(au => au.PasswordHash)
                    .Ignore(au => au.PhoneNumberConfirmed)
                    .Ignore(au => au.PrivateEmail)
                    .Ignore(au => au.PrivatePhoneNumber)
                    .Ignore(au => au.ProfileImagePath)
                    .Ignore(au => au.SecurityStamp)
                    .Ignore(au => au.TwoFactorEnabled)
                    .Ignore(au => au.UploadedFile)
                )
                .DefaultMappingFor<Crmlead>(m => m
                    .IndexName("crmleads")
                    .Ignore(crml => crml.Address)
                    .Ignore(crml => crml.City)
                    .Ignore(crml => crml.Company)
                    .Ignore(crml => crml.ContactPersonPhoneNumber)
                    .Ignore(crml => crml.Country)
                    .Ignore(crml => crml.CreateDate)
                    .Ignore(crml => crml.Customer)
                    .Ignore(crml => crml.CustomerContact)
                    .Ignore(crml => crml.IsDone)
                    .Ignore(crml => crml.IsSold)
                    .Ignore(crml => crml.PhaSEOneDescription)
                    .Ignore(crml => crml.Seller)
                    .Ignore(crml => crml.UploadedFiles)
                    .Ignore(crml => crml.Website)
                    .Ignore(crml => crml.ZipCode)
                )
                .DefaultMappingFor<Customer>(m => m
                    .IndexName("customers")
                    .Ignore(cust => cust.Activities)
                    .Ignore(cust => cust.Address)
                    .Ignore(cust => cust.City)
                    .Ignore(cust => cust.Company)
                    .Ignore(cust => cust.Contacts)
                    .Ignore(cust => cust.Country)
                    .Ignore(cust => cust.CreateDate)
                    .Ignore(cust => cust.Id)
                    .Ignore(cust => cust.Projects)
                    .Ignore(cust => cust.ZipCode)
                )
        }

private static void CreateIndices(IElasticclient client)
    {
        client.Indices.Create("users",index => index
            .Map<ApplicationUser>(x => x.AutoMap())
        );

        client.Indices.Create("crmleads",index => index
            .Settings(se => se
                .Analysis(a => a
                    .Analyzers(analyzer => analyzer
                        .Custom("substring_analyzer",analyzerDescriptor => analyzerDescriptor
                            .Tokenizer("standard")
                            .Filters("lowercase","substring")))
                    .TokenFilters(tf => tf
                        .NGram("substring",filterDescriptor => filterDescriptor
                            .MinGram(2)
                            .MaxGram(15))))
                .Setting("index.mapping.total_fields.limit","2000"))
            .Map<Crmlead>(x => x
                .AutoMap()
                .Properties(p => p
                    .Text(t => t
                        .Name(f => f.Name)
                        .Analyzer("substring_analyzer"))
                    .Text(t => t
                        .Name(f => f.CVRNumber)
                        .Analyzer("substring_analyzer"))
                    .Boolean(t => t
                        .Name(f => f.IsConverted))
                    .Text(t => t
                        .Name(f => f.ContactPersonName)
                        .Analyzer("substring_analyzer"))
                    .Text(t => t
                        .Name(f => f.ContactPersonEmail
                        ).Analyzer("substring_analyzer"))))
        );

        client.Indices.Create("customers",index => index
            .Settings(se => se
                    .Setting("index.mapping.total_fields.limit","2000"))
            .Map<Customer>(x => x.AutoMap())
        );
    }

技术是:

  1. nest 7.10.1
  2. .NET 核心 3.1
  3. Visual Studio 2019 - 社区版
  4. ElasticSearch 7.10.1
  5. Kibana 7.10.1

在这里做错了什么?提前致谢。

编辑

在研究了索引响应(如@Milan Gatyas 建议的那样)后,我发现我的 tokenfilter NGram.MaxGram 预期差异为 1,但结果为 13

.NGram("substring",filterDescriptor => filterDescriptor
                            .MinGram(2)
                            .MaxGram(15))))

为了解决这个问题,我将 max_ngram_diff 的设置设置为 15:

.Setting("index.max_ngram_diff","15"))

解决方法

为了解决这个问题,我将 max_ngram_diff 的设置设置为 15:

.Setting("index.max_ngram_diff","15"))

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...