首页 > 解决方案 > ElasticSearch 中的父子关系 - 在所有子文档组合中搜索一个句子

问题描述

我是弹性搜索的超级新手。我有一个用例似乎可以通过父子关系来解决。父文档包含 NGO 的描述。子文档包含发送给 NGO 的各种反馈。

Parent Doc structure
{
    name
    address
    description
}

Child doc
{
    feedbackContent
}

比方说,NGO-A 4 个反馈(意味着 4 个子文档)

另一个 NGO-B 有 2 个反馈(意味着 2 个子文档)

客户端应该能够查找已通过查询字符串中的所有术语的非政府组织。示例 - 客户搜索“最佳”和“位置”。

由于best存在于 child1 和 child2 中并且location存在于 child 4 中,因此 NGO-A 是有效的输出。但是,对于 NGO-B,child2 包含一个搜索词,而另一个搜索词不存在于任何其他子文档中,因此 NGO-B 不是有效结果。

我阅读了文档 - https://blog.mimacom.com/parent-child-elasticsearch/非常好,但无法得出结论是否可以这样做。

我试过的例子

PUT message_index
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0,
    "mapping.single_type": true
  },
  "mappings": {
    "doc": {
      "properties": {
        "ngo": {"type": "text"},
        "feedback": {"type": "text"},
        "ngo_relations": {
          "type": "join",
          "relations": {
            "ngo": "feedback"
          }
        }
      }
    }
  }
}

POST message_index/doc/_bulk
{"index": {"_id":1}}
{"name":"teach for india", "ngo_relations": {"name":"ngo"}}
{"index":{"_id":2}}
{"name":"hope for autism", "ngo_relations": {"name":"ngo"}}

PUT message_index/doc/3?routing=1
{"feedback":"best food","ngo_relations":{"name":"feedback", "parent":1}}

PUT message_index/doc/4?routing=1
{"feedback":"average location","ngo_relations":{"name":"feedback", "parent":1}}

PUT message_index/doc/5?routing=1
{"feedback":"awesome staff","ngo_relations":{"name":"feedback", "parent":1}}

PUT message_index/doc/6?routing=2
{"feedback":"best teachers","ngo_relations":{"name":"feedback", "parent":2}}

PUT message_index/doc/7?routing=2
{"feedback":"awesome overload","ngo_relations":{"name":"feedback", "parent":2}}

对于最佳和位置搜索,应返回为印度非政府组织教书。

没有命中:

GET message_index/_search
{
  "query": {
    "has_child": {
      "type": "feedback",
      "query": {
        "bool": {
          "must": {
            "term": {"feedback": "best"}
          },
          "must": {
            "term": {"feedback": "location"}
          }
        }
      }
    }
  }
}

两份文件均已退回

GET message_index/_search
{
  "query": {
    "has_child": {
      "type": "feedback",
      "query": {
        "bool": {
          "should": {
            "term": {"feedback": "best"}
          },
          "should": {
            "term": {"feedback": "location"}
          }
        }
      }
    }
  }
}

标签: elasticsearchsearchmappingparent-child

解决方案


这是可以做到的。您只是查询中的一个小错误。

在您的子查询中,您正在执行一个带有两个必须/应该的布尔值。因此,您的查询是:给我所有文档,使他们有一个孩子,这样孩子有两个(或“其中之一”,如果应该)术语“最佳”和“位置”。

然而,你想要的是:给我所有的文件,让他们有一个孩子,让孩子有“最佳”一词,还有一个孩子,让孩子有“位置”这个词。

调整您的查询如下:

GET message_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "has_child": {
            "type": "feedback",
            "query": {
              "term": {
                "feedback": "best"
              }
            }
          }
        },
        {
          "has_child": {
            "type": "feedback",
            "query": {
              "term": {
                "feedback": "location"
              }
            }
          }
        }
      ]
    }
  }
}

推荐阅读