2

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

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

其中电子邮件和旅行证件可以指代项目集合。

    {
    "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"}
                }
            }
        }
    }
}

有没有办法可以在弹性搜索中执行这种搜索?我可以用嵌套查询做到这一点吗?

4

1 回答 1

7

是的你可以。

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

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

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

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

对于下面的查询,我假设它travel_document不是嵌套的。

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

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

如果要进行精确匹配,则需要创建字段not_analyzed,在这种情况下,“Mary Jane”将被索引为单个术语“Mary Jane”,并且对“Mary”的查询将不匹配。不利的一面是,在这种情况下,您不能在名称字段上使用全文查询。

keyword同样,让电子邮件字段 not_analyzed (或使用带有标记器的自定义分析器 - 它不会标记字符串 - 和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
                           ]
                        }
                     }
                  ]
               }
            ]
         }
      }
   }
}
'
于 2013-01-30T10:42:27.653 回答