五、Elasticsearch.Net+Nest基本用法

基本用法

  • 安装Nest(安装后默认会装上Elasticsearch.Net),注意:版本尽量选择跟ES版本一致的

  • 批量初始化数据到ES

using Nest;

try
{
  // 测试环境SSL证书需要的设置
  ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
  ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) => { return true; });

  var uri = new Uri(ElasticsearchUrl);
  var setting = new ConnectionSettings(uri)
      .DisableDirectStreaming()// 默认情况下,请求和响应字节在调试信息中不可用,但可以通过设置DisableDirectStreaming在“连接设置”上全局启用
      .RequestTimeout(TimeSpan.FromSeconds(30))
      .DefaultFieldNameInferrer(name => name)// 按字段命初始化,防止IndexMany出现大小写字段名问题
      .BasicAuthentication(UserName, Password)// 设置账号密码
      .DefaultIndex("order")
      ;

  // 初始化ES客户端
  var client = new ElasticClient(setting);

  // 从关系库获取你要初始化进ES的数据
  var orders = GetOrders();

  // 批量初始化数据到ES
  // 方式一:
  var result = client.IndexMany(orders);
  if (result.IsValid)
  {
      Console.WriteLine("success");
  }
  else
  {
      Console.WriteLine("fail");
  }

  // 方式二:
  // 8.0版本IndexMany有点问题,可以使用api的方式
  var result = false;
  var client = new RestClient($"{ElasticsearchUrl}/order/_bulk");
  var request = new RestRequest(Method.POST);
  var authorization = $"{UserName}:{Password}";
  var authorizationBased64 = "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(authorization));
  request.AddHeader("Authorization", authorizationBased64);
  request.AddHeader("Content-Type", "application/json");
  // 这里可以改成从json文件中获取
  StringBuilder stringBuilder = new StringBuilder();
  foreach (var order in orders)
  {
      stringBuilder.Append("{\"index\":{\"_id\": \"" + order.COID + "\"}}");
      stringBuilder.Append("\r\n");
      stringBuilder.Append(JsonConvert.SerializeObject(order));
      stringBuilder.Append("\r\n");
  }
  var body = stringBuilder.ToString();
  request.AddParameter("application/json", body, ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  if (response.StatusCode == System.Net.HttpStatusCode.OK)
  {
      result = true;
  }
  else
  {
      result = false;
  }

  // 方式三:
  var request = new BulkRequest();
  request.Operations = orders.Select(o => new BulkIndexOperation<ElasticsearchOrder>(o) { Id = o.COID }).Cast<IBulkOperation>().ToList();
  var response = client.Bulk(request);
}
catch (Exception ex)
{
}
  • 删(官方抛弃过,实际使用会有点问题,实际开发中可以根据id去删除比较好,如果自定义Id在从关系库取数据的时候就能拿到Id了,不是自定义Id的话则要查询一次获取Id)
client.DeleteByQuery<ElasticsearchOrder>(d => d
    .Query(q => q
        .Match(m=>m.Field("Name").Query("DHL"))
    )
);
  • 改(Field更新)
// 更新指定Field:根据COID更新TotalPrice
var updateRes = client.UpdateByQuery<ElasticsearchOrder>(u => u
    .Index("order")
    .Query(q=>q
        .Match(m => m.Field("COID").Query(order.COID))
    )
    .Script(s=>s
        .Source("ctx._source.TotalPrice =  params.TotalPrice")
        .Params(p=>p.Add("TotalPrice", 6))
    )
    .Refresh(true)
);
  • 改(Doc更新)
// 更新Doc:根据_id更新整个Doc
var updateRes = client.Update<ElasticsearchOrder>(
        order.COID
        , f => f
            .Doc(order)
            .RetryOnConflict(3)
            .Refresh(Elasticsearch.Net.Refresh.True)
);
var must = new List<Func<QueryContainerDescriptor<ElasticsearchOrder>, QueryContainer>>();
// 查询单字段
must.Add(a=>a
    .Match(m=>m.Field("your field").Query("your value"))
);

// 查询 &&
must.Add(a => a
    .Bool(b=>b
        .Must(
            m => m.Match(h => h.Field("your field").Query("your value")),
            m => m.Match(h => h.Field("your field").Query("your value"))
        )
    )
);

// 查询日期
must.Add(a => a
    .DateRange(r => r
        .Field("your field").GreaterThanOrEquals(Convert.ToDateTime("your value"))
    )
);

// 查询日期区间
must.Add(a => a
    .Bool(b => b
        .Must(
            m => m.DateRange(r => r.Field("your field").GreaterThanOrEquals(Convert.ToDateTime("start time"))),
            m => m.DateRange(r => r.Field("your field").LessThanOrEquals(Convert.ToDateTime("end time")))
        )
    )
);

// 查询数值区间
must.Add(a => a
    .Bool(b => b
        .Must(
            m => m.Range(r => r.Field("your field").GreaterThanOrEquals(Convert.ToDouble("your value"))),
            m => m.Range(r => r.Field("your field").LessThanOrEquals(Convert.ToDouble("your value")))
        )
    )
);

// 模糊查询(这个方式性能可能不好,还没展开细细研究)
var value = "your value";
must.Add(a => a
    .Wildcard(w => w
        .Field("PONO").Value($"*{value}*")
    )
);

// 查询空字段
must.Add(a => a
    .Bool(b => b
        .Must(
            m => m.Range(r => r.Field("your field").GreaterThan(0)
        )
    )
));

// 查询某对象为null或者某字段有多个值
must.Add(a => a
    .Bool(b => b
        .Should(s => s
            .Bool(
                l => l.MustNot(m => m.Exists(e => e.Field("your entity")))), 
                l => l.Terms(t => t.Field("your field").Terms("your value")
            )
        )
    )
);

var from = 0;
var take = 10;
var should = new List<Func<QueryContainerDescriptor<ElasticsearchOrder>, QueryContainer>>();//如果有 || 需求使用
var res = client.Search<ElasticsearchOrder>(sd =>
    sd.Query(q => q.Bool(b => b.Must(must).Should(should)))
    .From(from)
    .Take(take)
    .Sort(s => s.Descending("InputTime"))
    .TrackTotalHits(true)
);
if (res.IsValid)
{

}
else
{

}
posted @ 2023-03-31 11:12  o李一波o  阅读(442)  评论(0编辑  收藏  举报