【问题标题】:Elasticsearch - Cardinality over Full Field ValueElasticsearch - 全字段值的基数
【发布时间】:2016-05-25 21:58:08
【问题描述】:

我有一个看起来像这样的文档:

{
   "_id":"some_id_value",
   "_source":{
      "client":{
         "name":"x"
      },
      "project":{
         "name":"x November 2016"
      }
   }
}

我正在尝试执行一个查询,该查询将为我获取每个客户的唯一项目名称的计数。为此,我在project.name 上使用cardinality 的查询。我确信这个特定客户只有4 唯一的项目名称。但是,当我运行查询时,我得到了 5 的计数,我知道这是错误的。

项目名称均包含客户名称。例如,如果客户是“X”,项目名称将是“X Testing November 2016”或“X Jan 2016”等。我不知道这是否是一个考虑因素。

这是文档类型的映射

{
   "mappings":{
      "vma_docs":{
         "properties":{
            "client":{
               "properties":{
                  "contact":{
                     "type":"string"
                  },
                  "name":{
                     "type":"string"
                  }
               }
            },
            "project":{
               "properties":{
                  "end_date":{
                     "format":"yyyy-MM-dd",
                     "type":"date"
                  },
                  "project_type":{
                     "type":"string"
                  },
                  "name":{
                     "type":"string"
                  },
                  "project_manager":{
                     "index":"not_analyzed",
                     "type":"string"
                  },
                  "start_date":{
                     "format":"yyyy-MM-dd",
                     "type":"date"
                  }
               }
            }
         }
      }
   }
}

这是我的搜索查询

{
   "fields":[
      "client.name",
      "project.name"
   ],
   "query":{
      "bool":{
         "must":{
            "match":{
               "client.name":{
                  "operator":"and",
                  "query":"ABC systems"
               }
            }
         }
      }
   },
   "aggs":{
      "num_projects":{
         "cardinality":{
            "field":"project.name"
         }
      }
   },
   "size":5
}

这些是我得到的结果(为简洁起见,我只发布了 2 个结果)。请发现 num_projects 聚合返回 5,但必须只返回 4,即项目总数。

{
   "hits":{
      "hits":[
         {
            "_score":5.8553367,
            "_type":"vma_docs",
            "_id":"AVTMIM9IBwwoAW3mzgKz",
            "fields":{
               "project.name":[
                  "ABC"
               ],
               "client.name":[
                  "ABC systems Pvt Ltd"
               ]
            },
            "_index":"vma"
         },
         {
            "_score":5.8553367,
            "_type":"vma_docs",
            "_id":"AVTMIM9YBwwoAW3mzgK2",
            "fields":{
               "project.name":[
                  "ABC"
               ],
               "client.name":[
                  "ABC systems Pvt Ltd"
               ]
            },
            "_index":"vma"
         }
      ],
      "total":18,
      "max_score":5.8553367
   },
   "_shards":{
      "successful":5,
      "failed":0,
      "total":5
   },
   "took":4,
   "aggregations":{
      "num_projects":{
         "value":5
      }
   },
   "timed_out":false
}

仅供参考:项目名称为ABCABC Nov 2016ABC retest NovemberABC Mobile App

【问题讨论】:

  • 你能提供一个关于你的测试场景的要点吗? (索引、一些数据样本和查询的映射)
  • @AndreiStefan - 我已经添加了您要求的详细信息。希望对您有所帮助。

标签: elasticsearch


【解决方案1】:

您的project.name 字段需要以下映射:

{
  "mappings": {
    "vma_docs": {
      "properties": {
        "client": {
          "properties": {
            "contact": {
              "type": "string"
            },
            "name": {
              "type": "string"
            }
          }
        },
        "project": {
          "properties": {
            "end_date": {
              "format": "yyyy-MM-dd",
              "type": "date"
            },
            "project_type": {
              "type": "string"
            },
            "name": {
              "type": "string",
              "fields": {
                "raw": {
                  "type": "string",
                  "index": "not_analyzed"
                }
              }
            },
            "project_manager": {
              "index": "not_analyzed",
              "type": "string"
            },
            "start_date": {
              "format": "yyyy-MM-dd",
              "type": "date"
            }
          }
        }
      }
    }
  }
}

它基本上是一个名为raw 的子字段,其中project.name 中的相同值被放入project.name.raw 中,但没有触及它(标记或分析它)。然后您需要使用的查询是:

{
  "fields": [
    "client.name",
    "project.name"
  ],
  "query": {
    "bool": {
      "must": {
        "match": {
          "client.name": {
            "operator": "and",
            "query": "ABC systems"
          }
        }
      }
    }
  },
  "aggs": {
    "num_projects": {
      "cardinality": {
        "field": "project.name.raw"
      }
    }
  },
  "size": 5
}

【讨论】:

    猜你喜欢
    • 2015-05-24
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多