• 基于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

  • 相关阅读:
    常用的正则表达式
    Spring
    Hibernate-04
    Hibernate-03
    Hibernate-02
    Hibernate-01
    装饰器(python)
    软件工程之小组选题报告
    小组项目之需求分析与原型设计
    关于group_concat函数拼接字符超长的问题
  • 原文地址:https://www.cnblogs.com/snaildev/p/8665445.html
Copyright © 2020-2023  润新知