我正在尝试使用NEST Client搜索多个索引Elasticsearch,我只是点击以下链接
[stackover post] How to search inside multiple indices using Nest ElasticSearch?
唯一的区别是我的索引已经存在,但没有返回
示例代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Elasticsearch.Net;
using Nest;
namespace ElasticSearchDemo
{
public class ExceptionData
{
public bool HasException { get; set; }
public string ExceptionMessage { get; set; }
}
public class ElasticSearchResponse : ExceptionData
{
public ISearchResponse<dynamic> elasticSearchResponse { get; set; }
}
public class ComponentTypES
{
public string ComponentID { get; set; }
public string Componentname { get; set; }
public string Summary { get; set; }
}
public class ProjectTypES
{
public string ProjectID { get; set; }
public string Projectname { get; set; }
public string Summary { get; set; }
public string Description { get; set; }
}
class Program
{
static void Main(string[] args)
{
// calling the function
var response = GetAllSearchResults("test", 0, 10);
}
public static ElasticClient GetElasticSearchCommonSearch()
{
ElasticClient elasticClient = null;
try
{
const string strElasticSearchURL = "http://localhost:9200/";
const string componentIndex = "componenttypeindex";
const string projectIndex = "projecttypeindex";
if (!string.IsNullOrEmpty(strElasticSearchURL))
{
ConnectionSettings connectionSettings = new ConnectionSettings(new Uri(strElasticSearchURL))
.DefaultIndex(componentIndex)
.DefaultMappingFor<ComponentTypES>(i => i.IndexName(componentIndex).TypeName("Componenttype"))
.DefaultMappingFor<ProjectTypES>(j => j.IndexName(projectIndex).TypeName("Projecttype"))
.DisableDirectStreaming()
.PrettyJson()
.OnRequestCompleted(callDetails =>
{
if (callDetails.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{callDetails.HttpMethod} {callDetails.Uri} \n" +
$"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
}
Console.WriteLine();
if (callDetails.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
}
);
elasticClient = new ElasticClient(connectionSettings);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message + " ConnectionObject for : Common Search");
}
return elasticClient;
}
public static ElasticSearchResponse GetAllSearchResults(string query = "test", int
page = 1, int pagesize = 10)
{
ElasticSearchResponse combinedResponse = new ElasticSearchResponse();
try
{
ElasticClient elasticClient = GetElasticSearchCommonSearch();
var clusterHealth = elasticClient.ClusterHealth();
if (clusterHealth.IsValid && string.Compare(clusterHealth.Status.ToString(), "red", true) != 0 && clusterHealth.ServerError == null)
{
string Componentindex = "componenttypeindex";
string Projectindex = "projecttypeindex";
var indices = Indices.Index(typeof(ComponentTypES)).And(typeof(ProjectTypES));
//elasticClient.Refresh(indices);
//TODO : Development time coding
if (null != (indices))
{
var indexExists = elasticClient.IndexExists(Indices.Index(Componentindex));
var projectExists = elasticClient.IndexExists(Indices.Index(Projectindex));
if (indexExists.Exists && indexExists.IsValid && projectExists.Exists && projectExists.IsValid)
{
//full text example 1
combinedResponse.elasticSearchResponse = elasticClient.Search<object>(s => s
.Index(indices)
.Type(Types.Type(typeof(ComponentTypES), typeof(ProjectTypES)))
.Query(q => (q
.MultiMatch(m => m
.Fields(f => f
.Field(Infer.Field<ComponentTypES>(ff => ff.Componentname))
.Field(Infer.Field<ComponentTypES>(ff => ff.Summary, 1.1))
)
.Operator(Operator.Or)
.Query(query)
) && +q
.Term("_index", Componentindex)) || (q
.MultiMatch(m => m
.Fields(f => f
.Field(Infer.Field<ProjectTypES>(ff => ff.Projectname))
.Field(Infer.Field<ProjectTypES>(ff => ff.Summary, 0.3))
)
.Operator(Operator.Or)
.Query(query)
) && +q
.Term("_index", Projectindex))
).From(page - 1)
.Size(pagesize)
);
//free text example 2
combinedResponse.elasticSearchResponse = elasticClient.Search<object>(s => s
.Index(indices)
.Type(Types.Type(typeof(ComponentTypES), typeof(ProjectTypES)))
.Query(q => (q
.MatchPhrase(m => m
.Field(Infer.Field<ComponentTypES>(ff => ff.Componentname))
.Query(query)
) && +q
.Term("_index", Componentindex)) || (q
.MatchPhrase(m => m
.Field(Infer.Field<ProjectTypES>(ff => ff.Projectname))
.Query(query)
)
) && +q
.Term("_index", Projectindex)
).From(page - 1)
.Size(pagesize)
);
}
else
{
combinedResponse.HasException = true;
combinedResponse.ExceptionMessage = "Index Not Found";
}
}
else
{
combinedResponse.HasException = true;
combinedResponse.ExceptionMessage = "Index Not Found In Config File";
}
}
else
{
combinedResponse.HasException = true;
combinedResponse.ExceptionMessage = "Error on connecting with ElasticSearch";
}
}
catch (Exception ex)
{
combinedResponse.HasException = true;
combinedResponse.ExceptionMessage = ex.Message;
return combinedResponse;
}
return combinedResponse;
}
}
}
弹性表架构:
PUT componenttypeindex
{
"mappings": {
"Componenttype":{
"properties":{
"ComponentID":{"type":"text"},
"Componentname":{"type":"text"},
"Summary":{"type":"text"}
}
}
}
}
PUT projecttypeindex
{
"mappings": {
"Projecttype":{
"properties":{
"ProjectID":{"type":"text"},
"Projectname":{"type":"text"},
"Summary":{"type":"text"},
"Description":{"type":"text"}
}
}
}
}
它应该返回查询匹配项,但是什么也没有返回 抱歉,我尝试过难看的代码格式,但是新的编辑器不会更改任何内容
更新: 我已经按照@RussCam的建议更新了查询中的索引值,但仍然没有预期的结果,而且当展开响应对象并直接在浏览器中运行URI参数时,它的所有结果有些奇怪,不确定为什么未显示响应计数
通过在POST上成功进行的低级调用构建的有效NEST响应:/ componenttypeindex%2Cprojecttypeindex / Componenttype%2CProjecttype / _search?typed_keys = true
我的POCO课程:
public class ComponentTypES
{
public string ComponentID { get; set; }
public string Componentname { get; set; }
public string Summary { get; set; }
}
public class ProjectTypES
{
public string ProjectID { get; set; }
public string Projectname { get; set; }
public string Summary { get; set; }
public string Description { get; set; }
}
样本数据:
PUT componenttypeindex/Componenttype/5342e739-1635-4021-baf2-55e25b95b8ec
{
"ComponentID":"5342e739-1635-4021-baf2-55e25b95b8ec",
"Componentname":"TestComponent1",
"Summary":"this is summary of test component1"
}
PUT componenttypeindex/Componenttype/90781386-8065-11e9-bc42-526af7764f64
{
"ComponentID":"90781386-8065-11e9-bc42-526af7764f64",
"Componentname":"TestComponent2",
"Summary":"this is summary of test component3"
}
PUT componenttypeindex/Componenttype/19871386-8065-11e9-bc42-526af7764f64
{
"ComponentID":"19871386-8065-11e9-bc42-526af7764f64",
"Componentname":"some xyz component test",
"Summary":"this is summary test of test xyz"
}
PUT projecttypeindex/Projecttype/5342e739-2019-4021-baf2-55e25b95b8ec
{
"ProjectID":"5342e739-2019-4021-baf2-55e25b95b8ec",
"Projectname":"Test Project1",
"Summary":"summary of Test Project1",
"Description":"Description of TestProject1"
}
PUT projecttypeindex/Projecttype/5342f739-2019-4021-baf2-55e25b95b8ba
{
"ProjectID":"5342f739-2019-4021-baf2-55e25b95b8ba",
"Projectname":"Test Project2",
"Summary":"summary of Test Project2",
"Description":"Description of TestProject1"
}
PUT projecttypeindex/Projecttype/6342f739-2020-4021-baf2-55e25b95b8ac
{
"ProjectID":"6342f739-2020-4021-baf2-55e25b95b8ac",
"Projectname":"some PQRS project",
"Summary":"summary of PQRS Project",
"Description":"Description of PQORS Project1"
}
答案 0 :(得分:1)
您的示例中有很多多余的信息,使操作起来很棘手,这增加了希望提供帮助的人所需要付出的努力。我是否可以建议您将示例缩减为最小,简洁但完整的示例,以说明您将来面临的问题;这确实有助于更快地解决问题的症结所在!
我认为根本的问题是索引映射的字段中的属性的大小写以及NEST默认发送的属性的大小写是不同的,因此{{1}中嵌套的must
子句由于字段大小写不同,由NEST生成的should
查询的}}子句绝不会与任何文档匹配。
NEST by default camel cases property names,但是示例中的索引映射和文档中的字段都是用pascal大小写的,因此NEST生成的字段名称将与映射中的字段名称不匹配。您可以使用bool
上的DefaultFieldNameInferrer(Func<string, string>)
方法来轻松更改NEST的现场套管行为。仅返回返回的字符串值的委托将保留字段名称,就像在POCO上一样。
这是一个完整而简洁的示例
ConnectionSettings
搜索得到的JSON查询是
private static void Main()
{
const string componentIndex = "componenttypeindex";
const string projectIndex = "projecttypeindex";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
.DefaultIndex(componentIndex)
.DefaultMappingFor<ComponentTypES>(i => i.IndexName(componentIndex).TypeName("Componenttype").IdProperty(f => f.ComponentID))
.DefaultMappingFor<ProjectTypES>(j => j.IndexName(projectIndex).TypeName("Projecttype").IdProperty(f => f.ProjectID))
.DefaultFieldNameInferrer(f => f)
.DefaultTypeName("_doc")
.DisableDirectStreaming()
.PrettyJson()
.OnRequestCompleted(callDetails =>
{
if (callDetails.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{callDetails.HttpMethod} {callDetails.Uri} \n" +
$"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
}
Console.WriteLine();
if (callDetails.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
});
var client = new ElasticClient(settings);
foreach (var index in new[] { componentIndex, projectIndex })
{
if (client.IndexExists(index).Exists)
client.DeleteIndex(index);
client.CreateIndex(index, c => c
.Mappings(m => {
if (index == projectIndex)
return m.Map<ProjectTypES>(mm => mm.AutoMap());
else
return m.Map<ComponentTypES>(mm => mm.AutoMap());
})
);
}
client.Bulk(b => b
.IndexMany(new [] {
new ComponentTypES
{
ComponentID = "5342e739-1635-4021-baf2-55e25b95b8ec",
Componentname = "TestComponent1",
Summary = "this is summary of test component1"
},
new ComponentTypES
{
ComponentID = "90781386-8065-11e9-bc42-526af7764f64",
Componentname = "TestComponent2",
Summary = "this is summary of test component3"
},
new ComponentTypES
{
ComponentID = "19871386-8065-11e9-bc42-526af7764f64",
Componentname = "some xyz component test",
Summary = "this is summary test of test xyz"
},
})
.IndexMany(new [] {
new ProjectTypES
{
ProjectID = "5342e739-2019-4021-baf2-55e25b95b8ec",
Projectname = "Test Project1",
Summary = "summary of Test Project1",
Description = "Description of TestProject1"
},
new ProjectTypES
{
ProjectID = "5342f739-2019-4021-baf2-55e25b95b8ba",
Projectname = "Test Project2",
Summary = "summary of Test Project2",
Description = "Description of TestProject1"
},
new ProjectTypES
{
ProjectID = "6342f739-2020-4021-baf2-55e25b95b8ac",
Projectname = "some PQRS project",
Summary = "summary of PQRS Project",
Description = "Description of PQORS Project1"
},
})
.Refresh(Refresh.WaitFor)
);
var query = "test";
var response = client.Search<object>(s => s
.Index(Indices.Index(typeof(ComponentTypES)).And(typeof(ProjectTypES)))
.Type(Types.Type(typeof(ComponentTypES), typeof(ProjectTypES)))
.Query(q =>
(q
.MultiMatch(m => m
.Fields(f => f
.Field(Infer.Field<ComponentTypES>(ff => ff.Componentname))
.Field(Infer.Field<ComponentTypES>(ff => ff.Summary, 1.1))
)
.Operator(Operator.Or)
.Query(query)
) && +q
.Term("_index", componentIndex)
) ||
(q
.MultiMatch(m => m
.Fields(f => f
.Field(Infer.Field<ProjectTypES>(ff => ff.Projectname))
.Field(Infer.Field<ProjectTypES>(ff => ff.Summary, 0.3))
)
.Operator(Operator.Or)
.Query(query)
) && +q
.Term("_index", projectIndex)
)
)
);
}
public class ComponentTypES
{
public string ComponentID { get; set; }
public string Componentname { get; set; }
public string Summary { get; set; }
}
public class ProjectTypES
{
public string ProjectID { get; set; }
public string Projectname { get; set; }
public string Summary { get; set; }
public string Description { get; set; }
}
返回5个结果
POST http://localhost:9200/componenttypeindex%2Cprojecttypeindex/Componenttype%2CProjecttype/_search?pretty=true&typed_keys=true
{
"query": {
"bool": {
"should": [
{
"bool": {
"filter": [
{
"term": {
"_index": {
"value": "componenttypeindex"
}
}
}
],
"must": [
{
"multi_match": {
"fields": [
"Componentname",
"Summary^1.1"
],
"operator": "or",
"query": "test"
}
}
]
}
},
{
"bool": {
"filter": [
{
"term": {
"_index": {
"value": "projecttypeindex"
}
}
}
],
"must": [
{
"multi_match": {
"fields": [
"Projectname",
"Summary^0.3"
],
"operator": "or",
"query": "test"
}
}
]
}
}
]
}
}
}