本文介绍如何使用ElasticsearchCRUD在多个索引和类型的Elasticsearch中进行搜索。 Elasticsearch提供了一个指数过滤器,一个类型过滤器和一个指数查询,可以在使用多个索引和类型时使用。 汇总搜索和计数请求也可以使用多个指数和类型执行。
该示例在单个索引中使用父,子,子孙映射,使用路由的父_Id
。 这确保了孙子文档和父文档被保存到同一个分片。 创建映射后,将在批量请求中添加3个文档。 结果索引在league
索引中有3种类型映射。
TTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 528
{
"leagues": {
"mappings": {
"team": {
"_parent": {
"type": "leaguecup"
},
"_routing": {
"required": true
},
"properties": {
"id": {
"type": "long"
},
"name": {
"type": "string"
},
"stadium": {
"type": "string"
}
}
},
"leaguecup": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "long"
},
"name": {
"type": "string"
}
}
},
"player": {
"_parent": {
"type": "team"
},
"_routing": {
"required": true
},
"properties": {
"age": {
"type": "integer"
},
"assists": {
"type": "integer"
},
"goals": {
"type": "integer"
},
"id": {
"type": "long"
},
"name": {
"type": "string"
},
"position": {
"type": "string"
}
}
}
}
}
}
在单个索引中搜索n个类型
要搜索包含多个类型的单个索引,需要创建一个新的ElasticsearchMapping
。 这将对象类型映射到所需的索引。
public class GlobalLeaguesElasticsearchMapping : ElasticsearchMapping
{
public override string GetIndexForType(Type type)
{
return "leagues";
}
public override string GetDocumentType(Type type)
{
return "";
}
}
然后将其添加到用于搜索的ElasticsearchContext
中
ElasticsearchMappingResolver.AddElasticSearchMappingForEntityType(typeof (object),
new GlobalLeaguesElasticsearchMapping());
现在使用对象类型的搜索将搜索leagues
索引中的任何文档类型。 使用路由,以便我们搜索正确的分片。
using (var context = new ElasticsearchContext(ConnectionString, Config))
{
context.TraceProvider = new ConsoleTraceProvider();
var result = context.Search<object>(new Search(),
new SearchUrlParameters
{
Routing = leagueId.ToString(CultureInfo.InvariantCulture)
});
Console.WriteLine("Found {0}, Expected 3", result.PayloadResult.Hits.Total);
}
搜索所有指标
还可以搜索Elasticsearch中的所有指标和所有类型。 为此,可以使用GlobalElasticsearchMapping
实用程序类。这被添加到对象类型的新上下文中。
_elasticsearchMappingResolver.AddElasticSearchMappingForEntityType(typeof(object), new GlobalElasticsearchMapping());
这可以用于计算服务器上的所有文档。
using (var context = new ElasticsearchContext(_connectionString, _elasticsearchMappingResolver))
{
long countValue = context.Count<object>();
Console.WriteLine("Global Count for all indices: {0}, Expected at least 3", countValue);
}
或者可以使用所有指标和类型进行搜索。
using (var context = new ElasticsearchContext(_connectionString, _elasticsearchMappingResolver))
{
var result = context.Search<object>(new Search()
{
Query = new Query(new MatchAllQuery())
});
}
使用来自全局搜索的数据
可以使用GetSourceFromJToken
方法来评估多重搜索的结果。
命中中的每个对象都作为JToken
返回,因为返回的类型被定义为一个对象。hit.TypeInIndex
可以用来找出它是什么样的文档。 这可以解析成一个类。
foreach (var hit in result.PayloadResult.Hits.HitsResult)
{
string type = hit.TypeInIndex;
if (type == "player")
{
var player = hit.GetSourceFromJToken<Player>();
Console.WriteLine("Found a player: {0}, {1}", player.Name, player.Id);
}
else if (type == "team")
{
var team = hit.GetSourceFromJToken<Team>();
Console.WriteLine("Found a team: {0}, {1}", team.Name, team.Id);
}
}
使用指标过滤器和类型过滤器搜索n个类型
搜索也可以使用IndicesFilter
和TypeFilter
过滤或过滤掉不同的类型。 以下代码片段过滤器用于team
类型,player
类型使用OrFilter
,并使用NoMatchFilter
属性删除leaguecup
类型。 如果设置了NoMatchFilterNone
,则所有未定义的类型都不会包含在结果中。
var search = new Search
{
Filter = new Filter(
new IndicesFilter(
new List<string> {"leagues"},
new OrFilter(
new List<IFilter>
{
new TypeFilter("team"),
new TypeFilter("player")
}
)
)
{
NoMatchFilter = new TypeFilter("leaguecup")
}
)
};
搜索可以发送到Elasticsearch如下:
using (var context = new ElasticsearchContext(_connectionString, _elasticsearchMappingResolver))
{
context.TraceProvider = new ConsoleTraceProvider();
var result = context.Search<object>(search,
new SearchUrlParameters
{
Routing = leagueId.ToString(CultureInfo.InvariantCulture)
});
Console.WriteLine("Found {0}, Expected 2", result.PayloadResult.Hits.Total);
}
这是以正确的Json作为HTTP Post请求消息体发送到Elasticsearch。
POST http://localhost:9200/_search?&routing=1 HTTP/1.1
Content-Type: application/json
Host: localhost:9200
Content-Length: 179
Expect: 100-continue
{
"filter": {
"indices": {
"indices": ["leagues"],
"filter": {
"or": { "filters": [{ "type": { "value": "team" } }, { "type": { "value": "player" } }] } },
"no_match_filter": {
"type": { "value": "leaguecup" } }
}
}
}
目前无法使用ElasticsearchCRUD在单个搜索请求中搜索n-indices。 这可能会在以后的版本中添加。 可以使用Indices
过滤器代替。