ElasticsearchCRUD使用(十七)【Elasticsearch搜索多个指标和类型】

本文介绍如何使用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个类型

搜索也可以使用IndicesFilterTypeFilter过滤或过滤掉不同的类型。 以下代码片段过滤器用于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过滤器代替。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值