实例
经过第一和第二步骤的操作我们已经把我们的基础数据存储在Elasticsearch服务器端了,可是我们要如何才可以搜索到我们需要的数据呢?
首先让我们来假设几个场景:
- 搜索姓名是:张小明
- 搜索邮箱是:[email protected]
- 搜索手机号是:15010886666
- 搜索年龄是:26
下面我们来一一分析这6个场景。一下搜索代码全部基于Beisen.SearchV3。
帮助类 参见: Helper.cs
- 姓名搜索(文本匹配)
我们在做姓名搜索的时候,根据不同的业务需求,我们希望你不管搜索的是不是全名都能匹配出包含这个词组的数据。比如:张,张小,小明。当然细心的你会发现我们是不希望张明的输入也出现张小明这显然不是那么的舒服。
public void MatchQuery()
{
IQuery match = new MatchQuery("Name", "张小明")
.Operator(Enums.Operator.And);
var result = Helper.Search(match);
}
- 邮箱搜索(通配符匹配) 我们当时在做邮箱搜索的时候,定义了一套叫做前匹配的规则。即是,只要你输入zhang,zhangxiao,zhangxiaoming@都可以得到你想要的[email protected],然后你输入beisen的话恐怕就只能得到邮箱是以Beisen开头的了。类似数据库的like方法
public void MatchQuery()
{
IQuery wildcard = new WildcardQuery("Email", "zhangxiaoming@*");
var result = Helper.Search(wildcard);
}
- 手机号搜索(精确匹配)
我们人为对于手机号的搜索就应该是完全匹配缺少任何一个数字都不应该出现结果。
public void TermQuery()
{
IQuery filtered = new TermQuery("Phone", "15010886666");
var result = Helper.Search(filtered);
}
- 年龄搜索(范围搜索)
我们通常在做年龄搜索的时候,需要搜索一段年龄范围的人。比如年龄在22-28岁之间的所有应聘者。
public void RangeFilter()
{
IFilter numericRange = new RangeFilter("Age", 22, 28);
var result = Helper.Search(numericRange);
}
复合查询
上面四个场景仅仅是单个条件的查询,我们的业务往往并不会如此简单。我们通常需要联合起来查询更为复杂的情况,比如: 查询姓名:张小明,性别:男,邮箱:[email protected]的应聘者:
这是我们需要在我们的代码中引入BoolFilter对象,它就像数据库SQL中的and,or用于连接不同的条件。
Public void Search()
{
BooleanFilter boolFilter = new BooleanFilter();
boolFilter.Must(new QueryFilter(new MatchQuery("Name", "张小明")
.Operator(Enums.Operator.And)));
boolFilter.Must(new TermQuery("Sex", "男"))
boolFilter.Must(new QueryFilter(new WildcardQuery("Email", "zhangxiaoming@*")))
var result = Helper.Search(boolFilter);
}
Tips: *搜索返回的Result中包含我们创建索引是的GUID,同时这个GUID正是我们存储Cassandra数据的唯一主键,这样一来我们便又可以从Cassandra中获取到我们当时存储的数据。
父子查询
上面所有的查询我们都是在单索引对象上进行的,但是在复杂的搜索场景我们可能需要跨对象进行查询,这个时候我们就需要引入一个新的查询方式:父子查询。
比如:我们现在拥有了一个ApplicantProfile对象用来记录应聘者的基本信息,应聘者可能还有些别的额外信息,比如学历,实习经验等等,这些对象可能存储在别的对象上,而我们在搜索的时候往往希望可以覆盖应聘者的所有信息这样才可以准确的达到我们搜素目的。
这个时候ApplicantProfile就可以设定为我们的 父对象
其他相关联信息比如 学习经历 实习经历 都可以划分为单个的 父对象下的子对象
public void HasChildFilter()
{
IFilter hasChild = new HasChildFilter("childType", new TermQuery("xueli", "benke"));
var result = Helper.Search("parentType", hasChild);
}
注意
父对象不需要额外申请,子对象需要额外再mapping中指定它的parentType名称,这样才能达到 父子对象关联。同时父子对象也是在同索引下成立,不可跨索引。