您可以使用 bool should 表达式动态构建查询。我将在下面提供完整的解决方案。使用适当的参数调用BuildQuery() 方法。
ISearchResponse<ElasticRequirement> BuildQuery(IElasticClient client, IEnumerable<string> terms, int slop)
{
return client.Search<ElasticRequirement>(s => s
.Query(q => q
.Bool(b => b
.Should(terms.Select(t => BuildPhraseQueryContainer(q, t, slop)).ToArray())))
.LowercaseExpandedTerms()
.Explain()
.Query(q => q.Fuzzy(f => f.PrefixLength(1).OnField(c => c.Title).OnField(c => c.Description))));
}
QueryContainer BuildPhraseQueryContainer(QueryDescriptor<ElasticRequirement> qd, string term, int slop)
{
return qd.MatchPhrase(m => m.OnField(f => f.Title).Query(term.ToLower()).Slop(slop)) ||
qd.MatchPhrase(m => m.OnField(f => f.Description).Query(term.ToLower()).Slop(slop));
}
对于terms = {"term1", "term2", "term3"} 和slop = 0,将由我的代码构建的Elasticsearch 搜索JSON 命令如下:
{
"explain": true,
"query": {
"bool": {
"should": [
{
"bool": {
"should": [
{
"match": {
"title": {
"type": "phrase",
"query": "term1",
"slop": 0
}
}
},
{
"match": {
"description": {
"type": "phrase",
"query": "term1",
"slop": 0
}
}
}
]
}
},
{
"bool": {
"should": [
{
"match": {
"title": {
"type": "phrase",
"query": "term2",
"slop": 0
}
}
},
{
"match": {
"description": {
"type": "phrase",
"query": "term2",
"slop": 0
}
}
}
]
}
},
{
"bool": {
"should": [
{
"match": {
"title": {
"type": "phrase",
"query": "term3",
"slop": 0
}
}
},
{
"match": {
"description": {
"type": "phrase",
"query": "term3",
"slop": 0
}
}
}
]
}
}
]
}
}
}
您可以调整此代码,使所有match 命令都在同一个should 节点下。我会让你自己弄清楚:)