【问题标题】:Elastic Search - complex query with array types and nested object properties弹性搜索 - 具有数组类型和嵌套对象属性的复杂查询
【发布时间】:2013-01-30 07:26:34
【问题描述】:

鉴于以下映射,我需要获得符合以下条件的结果

  1. 名字、姓氏、date_of_birth 和 Active = true OR
  2. 完全匹配
  3. 名字、姓氏完全匹配,Active = true 和 1 个电子邮件(可能的倍数)或
  4. 名字、姓氏、Active = true 和 1 个旅行证件 number 完全匹配

电子邮件和旅行证件可以指代物品的集合。

    {
    "profile":{
        "properties":{

            "date_of_birth":{
                "type":"date",
                "store":"no"
            },
            "first_name":{
                "type":"string",
                "store":"no"
            },
            "last_name":{
                "type":"string",
                "store":"no"
            },
            "email":{
                "type":"string",
                "store":"no"
            },
            "active":{
                "type":"string",
                "store":"no"
            },
            "travel_document":{
              "properties" : {
                   "countryOfCitizenship" : {"type" : "string"},
                   "countryOfIssue" : {"type" : "string"},
                   "expirationDate" : {"type" : "date"},
                   "nationality" : {"type" : "string"},
                   "number" : {"type" : "string"},
                   "addressLines" : {"type": "string"},
                   "issuedForAreaCode" : {"type": "string"},
                   "type" : {"type": "string"}
                }
            }
        }
    }
}

有没有办法可以在 elasticsearch 中执行这种搜索?我可以用Nested Queries 做到这一点吗?

【问题讨论】:

    标签: indexing elasticsearch


    【解决方案1】:

    是的,你可以。

    首先,回答您关于嵌套查询的问题:

    如果您需要在一组对象中查询 SAME OBJECT 中的多个字段(例如 travel_document.nationalitytravel_document.expirationDate,那么您需要将 travel_document 从类型 object 更改为类型 nested 并更改为使用嵌套查询。

    在您提供的示例查询中,您没有表明您需要此功能。相反,您问的是 ANY travel_document 是否有值。所以在这种情况下,您不需要使用嵌套功能。

    (如果您认为将来可能需要对相关字段进行查询,那么您可能确实想使用nested。您还可以设置include_in_root 将嵌套对象都作为单独的nested 对象进行索引并在主文档中)。

    对于下面的查询,我假设 travel_document 没有嵌套。

    第二:您在名称字段中使用“完全匹配”。

    默认情况下,会分析字符串字段,因此“Mary Jane”将被索引为术语 ['mary','jane']。如果您在该字段上运行查询以查找“Mary”,那么它将匹配,因为该字段确实包含“mary”。但是,这不是完全匹配。

    如果要进行精确匹配,则需要设置字段not_analyzed,在这种情况下,“Mary Jane”将被索引为单个术语“Mary Jane”,而对“Mary”的查询不会匹配。缺点是在这种情况下您无法在名称字段上使用全文查询。

    同样,将 email 字段设置为 not_analyzed 可能更有意义(或使用带有 keyword 标记器的自定义分析器 - 它不会标记字符串 - 和 lowercase 标记过滤器)。

    在下面的查询中,我假设您的姓名字段已被分析,而您的电子邮件字段未被分析:

    curl -XGET 'http://127.0.0.1:9200/my_index/properties/_search?pretty=1'  -d '
    {
       "query" : {
          "filtered" : {
             "query" : {
                "bool" : {
                   "must" : [
                      {
                         "match_phrase" : {
                            "first_name" : "mary jane"
                         }
                      },
                      {
                         "match_phrase" : {
                            "last_name" : "smith"
                         }
                      }
                   ]
                }
             },
             "filter" : {
                "and" : [
                   {
                      "term" : {
                         "active" : 1
                      }
                   },
                   {
                      "or" : [
                         {
                            "term" : {
                               "date_of_birth" : "1980-01-01"
                            }
                         },
                         {
                            "terms" : {
                               "email" : [
                                  "mary@smith.com",
                                  "maryjane@smith.com"
                               ]
                            }
                         },
                         {
                            "terms" : {
                               "travel_document.number" : [
                                  "1234",
                                  1235
                               ]
                            }
                         }
                      ]
                   }
                ]
             }
          }
       }
    }
    '
    

    【讨论】:

    • 感谢 DrTech 这正是我所需要的!
    • 感谢详尽的回答!只有一个挑剔:是的,我们可以。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 2019-11-13
    • 2021-09-01
    • 2015-09-24
    • 2018-08-06
    相关资源
    最近更新 更多