zoukankan      html  css  js  c++  java
  • 基于netcore对ElasitSearch客户端NEST查询功能的简单封装NEST.Repository

    NEST.Repository

    A simple encapsulation with NEST client for search data form elasticsearch.

    github

    API

    NESTReaderRepository

    TEntity Get(TKey id);
    TEntity Get(Func<QueryContainerDescriptor<TEntity>, QueryContainer> filterExp = null,
                Func<SourceFilterDescriptor<TEntity>, ISourceFilter> includeFieldExp = null,
                Expression<Func<TEntity, object>> sortExp = null, SortOrder sortType = SortOrder.Ascending);
    Tuple<long, List<TEntity>> GetList(Func<QueryContainerDescriptor<TEntity>, QueryContainer> filterExp = null,
                Func<SourceFilterDescriptor<TEntity>, ISourceFilter> includeFieldExp = null,
                Expression<Func<TEntity, object>> sortExp = null, SortOrder sortType = SortOrder.Ascending
               , int limit = 10, int skip = 0)

    NESTReaderRepositoryAsync

    Task<TEntity> GetAsync(TKey id);
    Task<TEntity> GetAsync(Func<QueryContainerDescriptor<TEntity>, QueryContainer> filterExp = null,
                Func<SourceFilterDescriptor<TEntity>, ISourceFilter> includeFieldExp = null,
                Expression<Func<TEntity, object>> sortExp = null, SortOrder sortType = SortOrder.Ascending);
    Task<Tuple<long, List<TEntity>>> GetListAsync(Func<QueryContainerDescriptor<TEntity>, QueryContainer> filterExp = null,
                Func<SourceFilterDescriptor<TEntity>, ISourceFilter> includeFieldExp = null,
                Expression<Func<TEntity, object>> sortExp = null, SortOrder sortType = SortOrder.Ascending
               , int limit = 0, int skip = 0)

    Depend on

    NEST 6.0.2
    Repository.IEntity 2.0.1 (or you can write IEntity<T> interface and you entity inherit it.)

    How to Use

    First, you need have an entity inherit IEntity<T>, T is type of PrimaryKey. eg

    [Serializable]
    [BsonIgnoreExtraElements]
    public class User : IEntity<long>
    {
        [BsonId]
        public long ID { get; set; }
    
        public double Age { get; set; }
    
        public double Sex { get; set; }
    
        public string Like { get; set; }
    }

    Second, you need have a repository inherit NESTReaderRepository or NESTReaderRepositoryAsync. eg

    public class UserRepo : NESTReaderRepository<User, long>
    {
        public static string connString = "http://localhost:9200/";
    
        public UserRepo()
            : base(connString)
        {
    
        }
    }

    Now, you can search data with simple api. eg

     static void Main(string[] args)
     {
        Repository.Container.RepositoryContainer.Register<UserRepo>();
        var userRepo = Repository.Container.RepositoryContainer.Resolve<UserRepo>();
    
        var user = userRepo.Get(9);
        var users = userRepo.GetList(
            filterExp: q => +q.Range(r => r.Field(f => f.Age).GreaterThan(13).LessThan(28)), 
            includeFieldExp: p => p.Includes(i => i.Fields(f => f.Age, f => f.Sex, f => f.Like)),
            sortExp: s => s.Age,
            sortType: Nest.SortOrder.Ascending,
            limit: 100,
            skip: 0
        );
     }

    How to write a Query

    0x00. Structured Search

    By default, documents will be returned in _score descending order, where the _score for each hit is the relevancy score calculated for how well the document matched the query criteria.

    q => q.DateRange(r => r
        .Field(f => f.{Field with DateTime Type})
        .GreaterThanOrEquals(new DateTime(2017, 01, 01))
        .LessThan(new DateTime(2018, 01, 01))
    )

    The benefit of executing a query in a filter context is that Elasticsearch is able to forgo calculating a relevancy score, as well as cache filters for faster subsequent performance.

     q => q.Bool(b => b.Filter(bf => bf
        .DateRange(r => r
            .Field(f => f.{Field with DateTime Type})
            .GreaterThanOrEquals(new DateTime(2017, 01, 01))
            .LessThan(new DateTime(2018, 01, 01))
            )
        )
    )

    0x01. Unstructured Search

    Full text queries (find all documents that contain "Russ" in the lead developer first name field)

    q => q.Match(m => m
        .Field(f => f.LeadDeveloper.FirstName)
        .Query("Russ")
    )

    0x02. Combining Search

    q => q.Bool(b => b
        .Must(mu => mu
            .Match(m => m
                .Field(f => f.LeadDeveloper.FirstName)
                .Query("Russ")
            ), mu => mu
            .Match(m => m
                .Field(f => f.LeadDeveloper.LastName)
                .Query("Cam")
            )
        )
        .Filter(fi => fi
            .DateRange(r => r
                .Field(f => f.StartedOn)
                .GreaterThanOrEquals(new DateTime(2017, 01, 01))
                .LessThan(new DateTime(2018, 01, 01))
            )
        )
    )

    use operator

    q => q.Match(m => m
            .Field(f => f.LeadDeveloper.FirstName)
            .Query("Russ")
        ) && q
        .Match(m => m
            .Field(f => f.LeadDeveloper.LastName)
            .Query("Cam")
        ) && +q
        .DateRange(r => r
            .Field(f => f.StartedOn)
            .GreaterThanOrEquals(new DateTime(2017, 01, 01))
            .LessThan(new DateTime(2018, 01, 01))
        )
    )

    Should ==> OR ==> ||
    Must ==> And ==> &&
    Must_Not ==> NOT==> !
    Filter ==> +

    the query will be converted to a bool query if use any operator, and the answer to the bool query is always yes or no , so that will not score.

    Reference

    https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/writing-queries.html

    https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/bool-queries.html

  • 相关阅读:
    Sql Server 2012 数据库同步方式 (发布、订阅)
    博客搬家通知
    无聊而又劳累的一天
    有没有大神知道国产加密算法SM2的详细介绍
    Android开发环境搭建helloworld程序创建(新手)
    debian下安装东西,遇到两个东西,记录下
    算法:扑克牌相关的一个简单功能示意(纯C实现)
    [51单片机学习笔记FIVE]----独立按键
    [51单片机学习笔记FOUR]----16*16LED点阵
    [51单片机学习笔记THREE]----继电器
  • 原文地址:https://www.cnblogs.com/snaildev/p/8665445.html
Copyright © 2011-2022 走看看