由于最近的一个项目中的搜索部分要用到 Elasticsearch 来实现搜索功能,苦于英文差及该方面的系统性资料不好找,在实现时碰到了不少问题,现把整个处理过程的代码分享下,给同样摸索的人一些借鉴,同时希望有经验的大牛发现有问题的地方不吝斧正!
查询入口
webapi 的部分代码,把查询条件封装到 eJobQueryPosition 中
var param = new eJobQueryPosition
{
IndustryPost = industryPost,
Region = region,
MinSalary = minSalary,
};
{
IndustryPost = industryPost,
Region = region,
MinSalary = minSalary,
};
//调用搜索
var gl = await _queryBusiness.QueryPositionsAsync(param, skip, top, string.Empty);
//处理结果
if (gl.IsError)
return FailActionRequest(gl.webapi_error);
if (gl.total <= 0)
{
return OkActionRequest(gl);
}
return OkListActionRequest(gl);
return FailActionRequest(gl.webapi_error);
if (gl.total <= 0)
{
return OkActionRequest(gl);
}
return OkListActionRequest(gl);
QueryPositionsAsync 部分代码
var resultData = await _queryPostion.QueryAsync(condition, skip, top, searchText);
//查看搜索语句
//var temp= Encoding.UTF8.GetString(resultData.RequestInformation.Request).Trim();
if (!resultData.Hits.Any())
{
return new GListResult<eJobPositionSimple>(new eJobPositionSimple[0]);
}
var result = resultData.Documents;
var g1 = result.Select(position => new eJobPositionSimple
{
Pstn_Id = position._id,
...
Phone = position.Phone,
Name = position.BrandName,
}).ToList();
return new GListResult<eJobPositionSimple>(g1, (int) resultData.Total);
//查看搜索语句
//var temp= Encoding.UTF8.GetString(resultData.RequestInformation.Request).Trim();
if (!resultData.Hits.Any())
{
return new GListResult<eJobPositionSimple>(new eJobPositionSimple[0]);
}
var result = resultData.Documents;
var g1 = result.Select(position => new eJobPositionSimple
{
Pstn_Id = position._id,
...
Phone = position.Phone,
Name = position.BrandName,
}).ToList();
return new GListResult<eJobPositionSimple>(g1, (int) resultData.Total);
QueryAsync部分代码
/// <summary>
/// 生成搜索客户端
/// </summary>
/// <returns></returns>
private static ElasticClient GetSearchClient()
{
var connectString = ConfigurationManager.ConnectionStrings["ElasticSearch"].ConnectionString;
var nodesStr = connectString.Split('|');
var nodes = nodesStr.Select(s => new Uri(s)).ToList();
var connectionPool = new SniffingConnectionPool(nodes);
var settings = new ConnectionSettings(connectionPool).SetDefaultIndex("position");
settings.SetDefaultPropertyNameInferrer(p => p.ToString());
var client = new ElasticClient(settings);
return client;
}
/// 生成搜索客户端
/// </summary>
/// <returns></returns>
private static ElasticClient GetSearchClient()
{
var connectString = ConfigurationManager.ConnectionStrings["ElasticSearch"].ConnectionString;
var nodesStr = connectString.Split('|');
var nodes = nodesStr.Select(s => new Uri(s)).ToList();
var connectionPool = new SniffingConnectionPool(nodes);
var settings = new ConnectionSettings(connectionPool).SetDefaultIndex("position");
settings.SetDefaultPropertyNameInferrer(p => p.ToString());
var client = new ElasticClient(settings);
return client;
}
//web.config 中 ElasticSearch 的设置 <add name="ElasticSearch" connectionString="http://192.168.1.7:7200" /> //默认为9200端口
public async Task<ISearchResponse<QPosition>> QueryAsync(eJobQueryPosition condition, int skip, int top, string searchText = "")
{
var client = GetSearchClient();
var resultData = await client.SearchAsync<QPosition>(s =>
s.Index("position").Type("tbJobPosition").
Query(
q => QueryContainerPosition(condition, searchText, q)).
SortDescending(f => f.UpdateTime).Skip(skip).Take(top));
return resultData;
}
/// <summary>
/// 生成职位查询表达式
/// </summary>
/// <param name="condition">职位条件</param>
/// <param name="searchText">查询的关键字</param>
/// <param name="q">用于返回的查询表达式</param>
/// <returns>返回用于搜索的表达式</returns>
private static QueryContainer QueryContainerPosition(eJobQueryPosition condition, string searchText, QueryDescriptor<QPosition> q)
{
var query = new QueryContainer();
//未过有效期
query &= q.Range(rr => rr.OnField(ff => ff.ExpireTime).GreaterOrEquals(DateTime.UtcNow.Date));
if (!string.IsNullOrWhiteSpace(searchText))
{
query &= QueryText(searchText, q, query);
}
return query;
/// 生成职位查询表达式
/// </summary>
/// <param name="condition">职位条件</param>
/// <param name="searchText">查询的关键字</param>
/// <param name="q">用于返回的查询表达式</param>
/// <returns>返回用于搜索的表达式</returns>
private static QueryContainer QueryContainerPosition(eJobQueryPosition condition, string searchText, QueryDescriptor<QPosition> q)
{
var query = new QueryContainer();
//未过有效期
query &= q.Range(rr => rr.OnField(ff => ff.ExpireTime).GreaterOrEquals(DateTime.UtcNow.Date));
if (!string.IsNullOrWhiteSpace(searchText))
{
query &= QueryText(searchText, q, query);
}
return query;
//该部分补充说明 在这里可以构造多个搜索条件 如下
/*
var query1 = new QueryContainer();
query1 = q.Term(s => s.OnField(ff => ff.BrandName).Value("szbrandname1"));
var query2 = new QueryContainer();
query2 = q.Term(s => s.OnField(ff => ff.BrandName).Value("szbrandname2"));
var query3 = new QueryContainer();
query2 = q.Term(s => s.OnField(ff => ff.BrandName).Value("szbrandname3"));
query = query1 || query2 || query3;
query1 = q.Term(s => s.OnField(ff => ff.BrandName).Value("szbrandname1"));
var query2 = new QueryContainer();
query2 = q.Term(s => s.OnField(ff => ff.BrandName).Value("szbrandname2"));
var query3 = new QueryContainer();
query2 = q.Term(s => s.OnField(ff => ff.BrandName).Value("szbrandname3"));
query = query1 || query2 || query3;
// or query = (query1 || query2) && query3;
//说明 各条件 || 等同 query 中的should; && 等同 must
//部分搜索条件可改用filter性能会更好,略
*/
}
}
/// <summary>
/// 搜索文本表达式,一定要放在所有表达式的最后
/// </summary>
/// <param name="searchText">搜索文本</param>
/// <param name="q">搜索表达式</param>
/// <param name="query">要返回的搜索表达式类</param>
/// <returns></returns>
private static QueryContainer QueryText(string searchText, QueryDescriptor<QPosition> q, QueryContainer query)
{
if (!string.IsNullOrWhiteSpace(searchText))
{
query = q.MatchPhrase(p => p.OnField(o => o.Descript).Query(searchText));
}
return query;
}
/// 搜索文本表达式,一定要放在所有表达式的最后
/// </summary>
/// <param name="searchText">搜索文本</param>
/// <param name="q">搜索表达式</param>
/// <param name="query">要返回的搜索表达式类</param>
/// <returns></returns>
private static QueryContainer QueryText(string searchText, QueryDescriptor<QPosition> q, QueryContainer query)
{
if (!string.IsNullOrWhiteSpace(searchText))
{
query = q.MatchPhrase(p => p.OnField(o => o.Descript).Query(searchText));
}
return query;
}
以上代码分别放到相应的cs文件中即可实现postion的搜索功能
部分应用要加哦
using System;
using System.Configuration;
using System.Linq;
using System.Threading.Tasks;
using **.Entity;
using Elasticsearch.Net.ConnectionPool;
using Nest;
using System.Configuration;
using System.Linq;
using System.Threading.Tasks;
using **.Entity;
using Elasticsearch.Net.ConnectionPool;
using Nest;
参考资料网址
http://nest.azurewebsites.net/nest/core/