首页 > 解决方案 > 使用 Elasticsearch .NET 和 NEST 6.x:如何从多个索引中获取文档

问题描述

var ids = new Dictionary<string, List<string>>();
ids["Topic"] = new List<string> {"KL7KJ2QBWD77yvpxyjvd", "374wJ2QBWD77yvpxDjpX", "B7499GMBWD77yvpxFzgW"};
ids["Prod"] = new List<string>();
ids["Account"] = new List<string>();

我做了这个流利的 NEST 查询:

var results = client.MultiGet(m => 
m.Index("topics").GetMany<Topic>(ids["Topic"])

.Index("prods").GetMany<Prod>(ids["Prod"])

.Index("accounts").GetMany<Account>(ids["Account"])

它正在生成下面的请求。我们看到请求仅使用最后一个索引集,即“accounts”(这不是我需要的):

http://localhost:9200/accounts/_mget?pretty=true
{
  "docs": [
    {
      "_type": "Topic",
      "_id": "KL7KJ2QBWD77yvpxyjvd"
    },
    {
      "_type": "Topic",
      "_id": "374wJ2QBWD77yvpxDjpX"
    },
    {
      "_type": "Topic",
      "_id": "B7499GMBWD77yvpxFzgW"
    }
  ]
}
# Response:
{
  "docs" : [
    {
      "_index" : "accounts",
      "_type" : "Topic",
      "_id" : "KL7KJ2QBWD77yvpxyjvd",
      "found" : false
    },
    {
      "_index" : "accounts",
      "_type" : "Topic",
      "_id" : "374wJ2QBWD77yvpxDjpX",
      "found" : false
    },
    {
      "_index" : "accounts",
          "_type" : "Topic",
      "_id" : "B7499GMBWD77yvpxFzgW",
      "found" : false
    }
  ]
}

事实上,我想在流利的 NEST 中创建以下(有效的)Elasticsearch 查询请求(没有特定索引):

http://localhost:9200/_mget?pretty=true
{
  "docs": [
    {
      "_index": "topics",
      "_type": "Topic",
      "_id": "KL7KJ2QBWD77yvpxyjvd"
    },
    {
      "_index": "topics",
      "_type": "Topic",
      "_id": "374wJ2QBWD77yvpxDjpX"
    },
    {
      "_index": "topics",
      "_type": "Topic",
      "_id": "B7499GMBWD77yvpxFzgW"
    }
  ]
}

有没有办法在流利的 NEST 中为每个 ids 列表指定每个索引/类型?

当然,如果我向 ids["Prod"] 和 ids["Account"] 添加特定的 id,这将为那些正确生成......例如:

http://localhost:9200/_mget?pretty=true
{
  "docs": [
    {
      "_index": "topics",
      "_type": "Topic",
      "_id": "KL7KJ2QBWD77yvpxyjvd"
    },
    {
      "_index": "prods",
      "_type": "Prod",
      "_id": "xxxxx"
    },
    {
      "_index": "accounts",
      "_type": "Account",
      "_id": "yyyyy"
    }
  ]
}

标签: c#elasticsearchnest

解决方案


每个都GetMany<T>(...)接受第二个参数,它是一个委托来进一步描述调用,包括提供一个索引名称

var ids = new Dictionary<string, List<string>>
{
    { "Topic", new List<string> { "topic1", "topic2", "topic3" } },
    { "Prod", new List<string> { "prod1", "prod2", "prod3" } },
    { "Account", new List<string> { "account1", "account2", "account3" } }
};

var multiGetResponse = client.MultiGet(m => m
    .GetMany<Topic>(ids["Topic"], (op, id) => op
        .Index("topics")
    )
    .GetMany<Prod>(ids["Prod"], (op, id) => op
        .Index("prods")
    )
    .GetMany<Account>(ids["Account"], (op, id) => op
        .Index("accounts")
    )
);

这会导致类似的请求

POST http://localhost:9200/_mget
{
  "docs": [
    {
      "_index": "topics",
      "_type": "topic",
      "_id": "topic1"
    },
    {
      "_index": "topics",
      "_type": "topic",
      "_id": "topic2"
    },
    {
      "_index": "topics",
      "_type": "topic",
      "_id": "topic3"
    },
    {
      "_index": "prods",
      "_type": "prod",
      "_id": "prod1"
    },
    {
      "_index": "prods",
      "_type": "prod",
      "_id": "prod2"
    },
    {
      "_index": "prods",
      "_type": "prod",
      "_id": "prod3"
    },
    {
      "_index": "accounts",
      "_type": "account",
      "_id": "account1"
    },
    {
      "_index": "accounts",
      "_type": "account",
      "_id": "account2"
    },
    {
      "_index": "accounts",
      "_type": "account",
      "_id": "account3"
    }
  ]
}

这些"_type"名称是通过小写从 CLR POCO 名称推断出来的,这可以通过覆盖连接设置上的类型名称推断器来更改。


推荐阅读