为什么我的查询会忽略我的过滤器聚合?

时间:2015-10-28 16:42:18

标签: elasticsearch

前言

我有4天的Elasticsearch 1.7.2经验。

设置

我有一组文件,每个文件都是UserUser的{​​{1}}个数字Answers通过UserAnswers链接。其中提供了user_answers.answer[]的文档参考。 answers数组是一个对象数组。

user_answers.answer[].correct是一个布尔字段,告诉我用户给出的答案是否正确。

目标

我想列出用户,并显示他们拥有的正确和错误答案的总数。

方法

到目前为止,我已经尝试了许多不同的方法,而我在这里所包含的方法与我在1.5天内尝试到目前为止一样接近。

  • 使用terms聚合按用户名为每个User创建一个存储桶。
  • 过滤每个桶只留下正确或错误的答案。
  • 计算已过滤答案的数量。

查询

{
    "size": 0,
    "filter": {
        "bool": {
            "must_not": {
                // Remove users who already have this award
                "term": {"awards_users.award_id": 2}
            }
        }
    },
    "aggs": {
        "users": {
            "terms": {"field": "username"},
            "aggs": {
                "correct": {
                    "filter": {
                        "term": {"user_answers.answer.correct": true}
                    },
                    "aggs": {
                        "count": {
                            "value_count": {
                                "field": "user_answers.answer.id"
                            }
                        }
                    }
                },
                // Same for incorrect, but inverted correct value
            }
        }
    }
} 

示例回复

{
  "key": "neon1024",
  "doc_count": 1,
  "correct": {
    "doc_count": 1,
    "count": {
      "value": 7 // Expected 1 correct & 6 incorrect
    }
  }
},

这是我正在测试的记录,我希望返回1而不是7。总共有7个答案,6个不正确,1个正确。我已在我的文档索引中验证过。

问题

出于某种原因,实际的过滤器似乎被忽略了,并且在桶中留下了所有可能的相关答案。因此,聚合是全部看到它们,而不是显示预期值。

问题

如何根据相关答案值的值使用聚合来分隔我的计数?

感谢您阅读我的长篇问题!

1 个答案:

答案 0 :(得分:0)

根据建议,您可能会将答案映射为object,而您应该使用nested类型。

使用嵌套类型,elasticsearch会将您的答案存储为链接到根目录的单个文档,并允许您对它们进行预期的聚合。您必须在查询中使用嵌套类型聚合来实现此目的。

所以我说最好像这样映射你的文件:

PUT /test
{
  "mappings" : {
    "your_type" : {
      "properties" : {
        "username" : {
          "type" : "string",
          "index" : "not_analyzed"
        },
        "user_answers" : {
          "type" : "nested",
          "properties" : {
            "id" : {
              "type" : "integer"
            },
            "answer" : {
              "type" : "string"
            },
            "correct" : {
              "type" : "boolean"
            }
          }
        }
      }
    }
  }
}

测试文件:

PUT /test/your_type/1
{
  "username": "neon1024",
  "user_answers": [
    {
      "id": 1,
      "answer": "answer1",
      "correct": true
    },
    {
      "id": 2,
      "answer": "answer2",
      "correct": true
    },
    {
      "id": 3,
      "answer": "answer3",
      "correct": false
    }
  ]
}

查询:

POST /test/_search?search_type=count
{
  "aggs": {
    "users": {
      "terms": {
        "field": "username"
      },
      "aggs": {
        "DiveIn": {
          "nested": {
            "path": "user_answers"
          },
          "aggs": {
            "CorrectVsIncorrect": {
              "terms": {
                "field": "user_answers.correct",
                "size": 2
              }
            }
          }
        }
      }
    }
  }
}

最终结果:

{
   "took": 6,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "users": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": "neon1024",
               "doc_count": 1,
               "DiveIn": {
                  "doc_count": 3,
                  "CorrectVsIncorrect": {
                     "doc_count_error_upper_bound": 0,
                     "sum_other_doc_count": 0,
                     "buckets": [
                        {
                           "key": "T",
                           "doc_count": 2
                        },
                        {
                           "key": "F",
                           "doc_count": 1
                        }
                     ]
                  }
               }
            }
         ]
      }
   }
}

其中"key": "T"表示正确答案,"doc_count": 2表示其数量。