在弹性搜索查询中将子项视为父项的字段

2023-12-19

我正在阅读 elasticsearch 的文档,此 [page][1] 讨论了如何使用将子项映射到父项类型_parent.

如果我有孩子叫email依附于父母称为account:

每种类型的字段:

account (http://localhost:9200/myapp/account/1)
========
id
name
some_other_info
state

email (http://localhost:9200/myapp/email/1?parent=1)
========
id
email
  • 我怎样才能在name现场accountemail现场email前提是state of account is active?

  • 有没有办法获得父母拥有的所有孩子(某种类型或任何类型)?

  • 为子文档建立索引时,是否可以将父文档作为 JSON 数据中的对象属性传递,而不是作为查询字符串的一部分?


在尝试了 imotov 的建议后,我提出了这个查询:

这是执行于http://localhost:9200/myapp/account/_search

{
  "query": {
    "bool": {
      "must": [
        {
          "prefix": {
            "name": "a"
          }
        },
        {
          "term": {
            "statuses": "active"
          }
        }
      ],
      "should": [
        {
          "has_child": {
            "type": "emailaddress",
            "query": {
              "prefix": {
                "email": "a"
              }
            }
          }
        }
      ]
    }
  }
}

问题是上面的内容没有给我任何与电子邮件匹配的帐户。

我想要的效果基本上是这样的:

  • 有一个搜索框
  • 用户开始输入内容,搜索框会自动完成。
  • 将根据名称检查用户的查询account或任何emailaddress type.
  • If accounts已匹配,只需返回即可。如果emailaddress匹配,返回其父帐户。
  • 每次搜索最多限制 x(例如 10)个帐户。

所以,我基本上需要能够OR在两种类型之间进行搜索并返回匹配的父类型。


测试数据:

curl -XPUT http://localhost:9200/test/account/1 -d '{
    "name": "John Smith",
    "statuses": "active"
}'

curl -XPUT http://localhost:9200/test/account/2 -d '{
    "name": "Peter Smith",
    "statuses": "active"
}'

curl -XPUT http://localhost:9200/test/account/3 -d '{
    "name": "Andy Smith",
    "statuses": "active"
}'

//Set up mapping for parent/child relationship

curl -XPUT 'http://localhost:9200/test/email/_mapping' -d '{
    "emails" : {
        "_parent" : {"type" : "account"}
    }
}'

curl -XPUT http://localhost:9200/test/email/1?parent=1 -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT http://localhost:9200/test/email/2?parent=1 -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT http://localhost:9200/test/email/3?parent=1 -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT http://localhost:9200/test/email/4?parent=2 -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT http://localhost:9200/test/email/5?parent=3 -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT http://localhost:9200/test/email/6?parent=3 -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

imotov 的解决方案对我有用。我发现的另一个解决方案是查询accounts for status = active,然后运行bool过滤结果并使用has_child关于孩子的类型和prefix on name在 - 的里面bool filter.


Elasticsearch 和关系数据库之间的一个重要区别是 Elasticsearch 无法执行联接。在elasticsearch中,您总是搜索单个索引或索引联合。但在父/子关系的情况下,可以使用子索引上的查询来限制父索引中的结果。例如,您可以在account type.

{
    "bool": {
        "must": [
            { 
                "text" : { "name": "foo" } 
            }, { 
                "term" : { "state": "active" } 
            }, {
                "has_child": {
                    "type": "email",
                    "query": {
                        "text": {"email": "bar" }
                    }
                }
            }
        ]
    }
}

此查询将仅返回父文档(不会返回子文档)。您可以使用此查询返回的父级 ID 来使用该字段查找该父级的所有子级_parent,默认情况下存储并建立索引。

{
    "term" : { "_parent": "1" } 
}

或者您可以将结果限制为仅包含包含该词的子项bar在该领域email:

{
    "bool": {
        "must": [
            { 
                "term" : { "_parent": "1" } 
            }, { 
                "text" : { "email": "bar" } 
            }
        ]
    }
}

我认为除非您使用的是,否则不可能在 json 中指定父级_批量索引 http://www.elasticsearch.org/guide/reference/api/bulk.html.

这是使用问题中提供的测试数据来实现电子邮件查找的方法:

#!/bin/sh
curl -XDELETE 'http://localhost:9200/test' && echo 
curl -XPOST 'http://localhost:9200/test' -d '{
    "settings" : {
        "number_of_shards" : 1,
        "number_of_replicas" : 0
    },
    "mappings" : {
      "account" : {
        "_source" : { "enabled" : true },
        "properties" : {
          "name": { "type": "string", "analyzer": "standard" },
          "statuses": { "type": "string",  "index": "not_analyzed" }
        }
      },
      "email" : {
        "_parent" : {
          "type" : "account"
        },
        "properties" : {
          "email": { "type": "string",  "analyzer": "standard" }
        }
      }
    }
}' && echo

curl -XPUT 'http://localhost:9200/test/account/1' -d '{
    "name": "John Smith",
    "statuses": "active"
}'

curl -XPUT 'http://localhost:9200/test/account/2' -d '{
    "name": "Peter Smith",
    "statuses": "active"
}'

curl -XPUT 'http://localhost:9200/test/account/3' -d '{
    "name": "Andy Smith",
    "statuses": "active"
}'

//Set up mapping for parent/child relationship

curl -XPUT 'http://localhost:9200/test/email/1?parent=1' -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT 'http://localhost:9200/test/email/2?parent=1' -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT 'http://localhost:9200/test/email/3?parent=1' -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT 'http://localhost:9200/test/email/4?parent=2' -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT 'http://localhost:9200/test/email/5?parent=3' -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPUT 'http://localhost:9200/test/email/6?parent=3' -d '{
    "email": "[email protected] /cdn-cgi/l/email-protection"
}'

curl -XPOST 'http://localhost:9200/test/_refresh'
echo
curl 'http://localhost:9200/test/account/_search' -d '{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "statuses": "active"
          }
        }
      ],
      "should": [
        {
          "prefix": {
            "name": "a"
          }
        },
        {
          "has_child": {
            "type": "email",
            "query": {
              "prefix": {
                "email": "a"
              }
            }
          }
        }
      ],
      "minimum_number_should_match" : 1
    }
  }
}' && echo
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在弹性搜索查询中将子项视为父项的字段 的相关文章

随机推荐