即使是不成熟的尝试,也胜于胎死腹中的策略。

关于使用elasticsearch nested类型查询多个重复匹配的问题

Elasticsearch | 作者 lemonzero | 发布于2021年08月17日 | 阅读数:2200

首先说一下我的需求:查询条件只有student.en_name一个,需求是查询所有班级里,有两个或者以上的人名字是 张一 的所有结果下边是模拟数据
1.索引mapping如下,student为nested类型;
GET /index_class/_mapping


{
  "index_class" : {
    "mappings" : {
      "properties" : {
        "id" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text"
        },
        "student" : {
          "type" : "nested",
          "properties" : {
            "en_name" : {
              "type" : "keyword"
            },
            "id" : {
              "type" : "keyword"
            },
            "name" : {
              "type" : "text",
              "analyzer" : "ik_max_word"
            }
          }
        },
        "type" : {
          "type" : "keyword"
        }
      }
    }
  }
}
2.放入数据
{
"id": 1,
"name": "一班",
"type": "A",
"student": [{
"name": "张一",
"id": "1",
"en_name": "zhangyi"
},
{
"name": "张一",
"id": "2",
"en_name": "zhangyi"
},
{
"name": "张三",
"id": "3",
"en_name": "zhangsan"
},
{
"name": "张三",
"id": "4",
"en_name": "zhangsan"
}]
}, {
"id": 2,
"name": "二班",
"type": "A",
"student": [{
"name": "张一",
"id": "1",
"en_name": "zhangyi"
},
{
"name": "张二",
"id": "2",
"en_name": "zhanger"
},
{
"name": "张三",
"id": "3",
"en_name": "zhangsan"
},
{
"name": "张四",
"id": "4",
"en_name": "zhangsi"
}]
}


需求是使用student.en_name,查询到只有两个 张一 的一班结果,不查到一个张一的二班的结果,需要怎么写查询?请大神指教一下
下边是我的查询
POST /index_class/_search
{
"from":0,
"size":10,
"query":{
"bool":{
"must":[
{
"nested":{
"query":{
"bool":{
"must":[
{
"match":{
"student.en_name":"zhangyi"

}
}
]
}
},
"path":"student"
}
},
{
"nested":{
"query":{
"bool":{
"must":[
{
"match":{
"student.en_name":"zhangyi"

}
}
]
}
},
"path":"student"
}
}
]
}
}
}
已邀请:

BetterLevi

赞同来自: HarryXie

 
{
"query": {
"function_score": {
"query": {
"match_all": {}
},
"functions": [
{
"script_score": {
"script": {
"lang": "painless",
"source": "int count = 0; def st = params._source['student']; for(int i=0; i< st.size(); i++) {if(st.get(i)['en_name'] == 'zhangyi') {count = count + 1;}} return count;"
}
}
}
],
"min_score": 2
}
}
}

BetterLevi

赞同来自:

{
"query": {
"bool": {
"filter": {
"nested": {
"path": "student",
"query": {
"bool": {
"filter": {
"script": {
"script": "int count = 0; def st = doc['student.en_name']; for(int i=0; i< st.length; ++i) {if(st[i] == 'zhangyi') {count++;}} if(count>=2){return true;} else {return false;}"
}
}
}
}
}
}
}
}
}

lemonzero

赞同来自:

POST /index_class/_search
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "student",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "student.en_name": "zhangyi"
                    }
                  }
                ],
                "filter": [
                  {
                    "script": {
                      "script": {
                        "lang": "painless",
                        "params": {
                          "enname": "zhangyi",
                          "size": 2
                        },
                        "source": "def s=0;def list = doc['student.en_name'];for(n in list){if(n==params['enname']){s++;}} return s==2;"
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

QQ浏览器截图20210818202718.png

 

要回复问题请先登录注册