假设我们有一个学生,带有(嵌套的)分数的(嵌套)列表,如下所示:
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 查询,以获取所有分数在7到10之间至少2的所有学生。
因此,例如,如果某个学生的得分为{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命中)的连接。即使它确实起作用,我仍然需要一些更优雅的东西,因为如果我们有四个以上的允许值,这将很痛苦。
更新
我尝试了以下脚本,但也得到了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)"""
}
}
]
}
}
}
}
}
最佳答案
一段时间后,我发现了一个有效的查询:
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
,我想),但是现在,我将其保留为最终答案。
关于c# - ElasticSearch从指定术语中查找具有不同嵌套列表元素的索引对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44594825/