假设我们有一个学生,其中包含得分的嵌套列表,如下所示:
public class Student
{
public string FullName { get; set; }
public List<Score> Scores { get; set; } = new List<int>();
}
public class Score
{
public int Value { get; set; }
}
如何使用 NEST (或简单查询)编写 ElasticSearch 查询,以便让所有至少有2个不同分数的学生从7到10。
因此,例如,如果一个学生得分{2,7,10}或{8,10},他应该在我们的结果中,而一个学生{10,6,5}或{8,8}或{2,7}不应该进入我们的结果。
我想出的是:
GET /index/student/_search
{
"query": {
"nested": {
"path": "scores",
"query": {
"bool": {
"should":
[
{
"bool": {
"filter": [
{
"terms": {
"scores.value": [7, 10]
}
},
{
"terms":{
"scores.value": [8, 9]
}
}
]
}
},
{
"bool": {
"filter": [
{
"terms": {
"scores.value": [7, 8]
}
},
{
"terms":{
"scores.value": [9, 10]
}
}
]
}
}
]
}
}
}
}
}
但ElasticSearch似乎不允许 TERMS 查询的连接(返回0次点击)。即使它确实有效,我仍然需要更优雅的东西,因为如果我们有超过4个允许值,这将成为一种痛苦。
更新
我已尝试过以下脚本,但也获得了0个结果:
GET /index/student/_search
{
"query": {
"nested": {
"path": "scores",
"query": {
"bool": {
"filter": [
{
"exists": {
"field": "scores"
}
},
{
"script": {
"script": """
boolean condition = false;
def availableScores = [7, 8, 9, 10];
def scores = doc['scores.id'].values;
for (int i = 0; i < scores.length; i++)
for(int j = 0; j < availableScores.length; j++)
if (scores[i] == availableScores[j])
{
if (condition == true)
return (true);
condition = true;
availableScores.remove(j);
break;
}
return (false)"""
}
}
]
}
}
}
}
}
答案 0 :(得分:1)
过了一会儿,我找到了一个有效的查询:
GET /index/student/_search
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"nested": {
"path": "scores",
"query": {
"terms": {
"scores.value": [
7,
10
]
}
}
}
},
{
"nested": {
"path": "scores",
"query": {
"terms": {
"scores.value": [
8,
9
]
}
}
}
}
]
}
},
{
"bool": {
"must": [
{
"nested": {
"path": "scores",
"query": {
"terms": {
"scores.value": [
7,
9
]
}
}
}
},
{
"nested": {
"path": "scores",
"query": {
"terms": {
"scores.value": [
8,
10
]
}
}
}
}
]
}
}
]
}
}
}
这里的技巧是将1个嵌套查询分成多个,并将它们放在should
查询中。
我仍然想要一个更优雅的解决方案(通过script
,我猜),但就目前而言,我将其作为最终答案。