美文网首页
ElasticSearch.NET & NEST —— C#的E

ElasticSearch.NET & NEST —— C#的E

作者: 谁有羊毛 | 来源:发表于2021-01-21 10:17 被阅读0次

    NEST 基础使用

    1. 建立连接,创建client

    var nodes = new[]
                {
        new Uri("http://localhost:9200")
    };
    
    var pool = new StaticConnectionPool(nodes);
    var settings = new ConnectionSettings(pool); ;
    var client = new ElasticClient(settings);
    

    2.获取所有索引

    var indexs = client.Cat.Indices();
    

    3. 创建一个索引

    • 可以增加多个map 之类,多个之类相当于属性拼成了一个大表
    • subClass1 与 subClass2之间如果有重复名称的字段,那么先map的会保留,后续的不会覆盖前面的同名字段 —— 如下例:先map的Company,后map的Employee,那么生成index的时候,实际生成的是Company
      的 字段, 也就是 string 类型的 Name
    client.Indices.Create("indexTest1", c => c
        .Map(m => m
            .AutoMap<Company>()
            .AutoMap<Employee>()
        )
    );
    public abstract class Document
    {
        public JoinField Join { get; set; }
    }
    public class Company : Document
    {
        public string Name { get; set; }
        public List<Employee> Employees { get; set; }
    }
    public class Employee : Document
    {
        public int Name { get; set; }
        public int Salary { get; set; }
        public DateTime Birthday { get; set; }
        public bool IsManager { get; set; }
        public List<Employee> Employees { get; set; }
        public TimeSpan Hours { get; set; }
    }
    
    image.png

    4. 给Es的对象加上对应的解析特性

    [ElasticsearchType(RelationName = "employee")]
    public class Employee
    {
        [Text(Name = "first_name", Norms = false, Similarity = "LMDirichlet")]
        public string FirstName { get; set; }
    
        [Text(Name = "last_name")]
        public string LastName { get; set; }
    
        [Number(DocValues = false, IgnoreMalformed = true, Coerce = true)]
        public int Salary { get; set; }
    
        [Date(Format = "MMddyyyy")]
        public DateTime Birthday { get; set; }
    
        [Boolean(NullValue = false, Store = true)]
        public bool IsManager { get; set; }
    
        [Nested]
        [PropertyName("empl")]
        public List<Employee> Employees { get; set; }
    
        [Text(Name = "office_hours")]
        public TimeSpan? OfficeHours { get; set; }
    
        [Object]
        public List<Skill> Skills { get; set; }
    }
    
    public class Skill
    {
        [Text]
        public string Name { get; set; }
    
        [Number(NumberType.Byte, Name = "level")]
        public int Proficiency { get; set; }
    }
    

    5. 查询

    • 最简单的查询示例
    var qr1 = client.Search<NodeLogSearchEntity>(s => s
                    .Index("log.test_mix-2021.01.18")
                    .Query(q => q
                        .MatchAll()
                        )
                );
    
    • 较为复杂的查询
    var result = client.Search<VendorPriceInfo>(
                    s => s
                        .Explain() //参数可以提供查询的更多详情。
                        .FielddataFields(fs => fs //对指定字段进行分析
                            .Field(p => p.vendorFullName)
                            .Field(p => p.cbName)
                        )
                        .From(0) //跳过的数据个数
                        .Size(50) //返回数据个数
                        .Query(q =>
                            q.Term(p => p.vendorID, 100) // 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型):
                            &&
                            q.Term(p => p.vendorName.Suffix("temp"), "姓名") //用于自定义属性的查询 (定义方法查看MappingDemo)
                            &&
                            q.Bool( //bool 查询
                                b => b
                                    .Must(mt => mt //所有分句必须全部匹配,与 AND 相同
                                        .TermRange(p => p.Field(f => f.priceID).GreaterThan("0").LessThan("1"))) //指定范围查找
                                    .Should(sd => sd //至少有一个分句匹配,与 OR 相同
                                        .Term(p => p.priceID, 32915),
                                        sd => sd.Terms(t => t.Field(fd => fd.priceID).Terms(new[] {10, 20, 30})),//多值
                                        //||
                                        //sd.Term(p => p.priceID, 1001)
                                        //||
                                        //sd.Term(p => p.priceID, 1005)
                                        sd => sd.TermRange(tr => tr.GreaterThan("10").LessThan("12").Field(f => f.vendorPrice))
                                    )
                                    .MustNot(mn => mn//所有分句都必须不匹配,与 NOT 相同
                                        .Term(p => p.priceID, 1001)
                                        ,
                                        mn => mn.Bool(
                                            bb=>bb.Must(mt=>mt
                                                .Match(mc=>mc.Field(fd=>fd.carName).Query("至尊"))
                                            ))
                                    )
                                )
                        )//查询条件
                    .Sort(st => st.Ascending(asc => asc.vendorPrice))//排序
                    .Source(sc => sc.Include(ic => ic
                        .Fields(
                            fd => fd.vendorName,
                            fd => fd.vendorID,
                            fd => fd.priceID,
                            fd => fd.vendorPrice))) //返回特定的字段
                   );
    

    二、Elasticsearch的文本的查询

    es的text数据存储,实际上插入一条数据的时候,会默认的分词,分词后再倒排索引,后面方便查询。text在被index的时候,会保留一个它的子字段 text.keyword,改字段是不被分词的text字段。(ps: map的时候也可以设置不分析)

    0. 查看一个text的分析

    • 在kibana里面的devtool里面执行即可
    POST _analyze
    {
      "analyzer": "standard",
      "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
    }
    
    标准分词器分词

    1. 精准匹配

    属性 查询之key分词的查询json 查询之key不分词的查询json
    es中数据 => 分词 { "query": { "match": { "key": "value" } } } { "query": { "term": { "key": "value" } } }
    es中数据 => 不分词 { "query": { "match": { "key.keyword": "value" } } } { "query": { "term": { "key.keyword": "value" } } }

    2. 模糊匹配 —— 字符串 Levenshtein distance =》 fuzzy

    fuzzy匹配是根据 Levenshtein distance 来判断是否匹配,一般长度为 0,1,2 太大将不会匹配,因为结果太多了

    • eg: cat,kat,他们就一个字符不同所以 Levenshtein distance("kat","cat") = 1
    属性 fuzzy的key的查询json
    es中数据 => 分词 { "query": { "fuzzy": { "key": { "value": "cat" "fuzziness": "1" } } } }
    es中数据 => 不分词 { "query": { "fuzzy": { "key.keyword": { "value": "cat" "fuzziness": "1" } } } }

    3. 模糊匹配 —— 使用通配符 wildcard 匹配 =》 WildCard

    WildCard 匹配 就很像我们SQL里面的like匹配 只不过这里使用 *或者? 来匹配

    • eg: kiy, kity, kimchy 加入要匹配这三个
    属性 fuzzy的key的查询json
    es中数据 => 分词 { "query": { "wildcard": { "key": { "value": "ki*y" } } } }
    es中数据 => 不分词 { "query": { "wildcard": { "key.keyword": { "value": "ki*y" } } } }

    相关文章

      网友评论

          本文标题:ElasticSearch.NET & NEST —— C#的E

          本文链接:https://www.haomeiwen.com/subject/laeqzktx.html