Elasticsearch父子级查询及祖孙辈parent/child关联查询

一、简介

ElasticSearch是一个基于Lucene的搜索服务器,它提供了一个基于RESTful web接口分布式多用户能力的全文搜索引擎,ElasticSearch是用于Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。

二、parent/child关系

可以为两个完全分开的文档,按某种对应关系以一对多的关系映射从而关联上,更新符文档时,子文档不会重新被索引,子文档更新不会影响父文档或者其他子文档,

三、关联查询

这里我们先创建一个es,

PUT school_test
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "class_name": {
        "type": "keyword"
      },
      "teacher_name": {
        "type": "keyword"
      },
      "student_name": {
        "type": "keyword"
      },
      
      "index_create_time_dt": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "index_update_time_dt": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },

      "parent_child_t": {
        "type": "join",
        "eager_global_ordinals": true,
        "relations": {
          "parent": "child"
        }
      },

      "routing": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

 

 结构中含有class_name, teacher_name, student_name。其中关联关系为parent-child,

创建测试数据

Elasticsearch父子级查询及祖孙辈parent/child关联查询

 

 Elasticsearch父子级查询及祖孙辈parent/child关联查询

 

 通过子级查询父级(has_child)

例:通过子级条件class_name=“教师1”查询出所在的班级

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "role": {
              "value": "class"
            }
          }
        },
        {
          "has_child": {
            "type": "child",
            "query": {
              "term": {
                "class_name": {
                  "value": "教师1"
                }
              }
              
            }
          }
        }
      ]
    }
  }
}

  查询结果如图:

Elasticsearch父子级查询及祖孙辈parent/child关联查询

 通过父级查询子级(has_parent)

例:通过父级条件class_name="班级1",查询出所有教师

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "role": {
              "value": "teacher"
            }
          }
        },
        {
          "has_parent": {
            "parent_type": "parent",
            "query": {
              "term": {
                "class_name": {
                  "value": "班级1"
                }
              }
            }
          }
        }
      ]
    }
  }
}

  查询结果如图所示:

Elasticsearch父子级查询及祖孙辈parent/child关联查询

 

 但是如果整体的结构为三层结构,即班级对应 -> 教师 -> 学生,映射关系parent-child,已经不能满足查询条件了

例如通过教师查询对应的学生,

Elasticsearch父子级查询及祖孙辈parent/child关联查询

 

 这个查询条件得到的查询结果将为空,所以需要将对应关系变为

"relations": {
"class": "teacher",
"teacher": "student"
}

祖孙辈关联查询

三级关联以上可以看为祖孙被查询,例如通过class_name="班级2“查询出所有学生

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "role": {
              "value": "student"
            }
          }
        },
        {
          "has_parent": {
            "parent_type": "teacher",
            "query": {
              "has_parent": {
                "parent_type": "class",
                "query": {
                  "term": {
                    "class_name": {
                      "value": "班级2"
                    }
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

  查询结果:

Elasticsearch父子级查询及祖孙辈parent/child关联查询

 

 注:建立对应关系时,要注意父文档和子文档在es的同一分片上,这里保持routing统一才可以关联查询到数据

上一篇:vue 过滤使用(搜索)


下一篇:js实现模糊查询