ElasticSearch: 在嵌套数组中搜索字段

7
我对ES还比较陌生,但正在使用它来进行我的新项目。开始时,我有一个简单的客户映射,其中包含名字、姓氏和支付信息对象列表。如果我在SQL中执行此操作,它将类似于客户表和具有1:多关系的付款信息表。
这是我想要做的简单示例: https://gist.github.com/anonymous/6109593 我希望能够基于paymentInfos嵌套数组中的任何匹配项查找任何客户,即查找任何具有billingZip 10101的paymentInfo的用户。但是,此查询未返回结果,我不确定原因。是否有人可以指导我为什么此查询不起作用,以及我是否可以对查询或映射进行任何更改以使其正确返回用户?
谢谢!
1个回答

10

应该使用嵌套查询来搜索嵌套字段:

echo "Deleting old ElasticSearch index..."
curl -XDELETE 'localhost:9200/arrtest'
echo
echo "Creating new ElasticSearch index..."
curl -XPUT 'localhost:9200/arrtest/?pretty=1' -d '{
   "mappings" : {
      "cust2" : {
         "properties" : {
            "firstName" : {
               "type" : "string",
               "analyzer" : "string_lowercase"
            },
            "lastName" : {
               "type" : "string",
               "analyzer" : "string_lowercase"
            },
            "paymentInfos": {
                "properties": {
                    "billingZip": {
                        "type": "string",
                        "analyzer": "string_lowercase"
                    },
                    "paypalEmail": {
                        "type": "string",
                        "analyzer": "string_lowercase"
                    }
                },
                "type": "nested"
            }
         }
      }
   },

   "settings" : {
      "analysis" : {
         "analyzer" : {
            "uax_url_email" : {
               "filter" : [ "standard", "lowercase" ],
               "tokenizer" : "uax_url_email"
            },

            "string_lowercase": {
                "tokenizer" : "keyword",
                "filter" : "lowercase"
            }
         }
      }
   }
}
'
echo
echo "Index recreation finished"

echo "Inserting one record..."
curl -XPUT 'localhost:9200/arrtest/cust2/1' -d '{
    "firstName": "john",
    "lastName": "smith",

    "paymentInfos": [{
        "billingZip": "10101",
        "paypalEmail": "foo@bar.com"
    }, {
        "billingZip": "20202",
        "paypalEmail": "foo2@bar2.com"
    }]
}
'
echo
echo "Refreshing index to make new records searchable"
curl -XPOST 'localhost:9200/arrtest/_refresh' 
echo
echo "Searching for record..."
curl -XGET 'localhost:9200/arrtest/cust2/_search?pretty=1' -d '{
    "sort": [],
    "query": {
        "bool": {
            "should": [],
            "must_not": [],
            "must": [{
                "nested": {
                    "query": {
                        "query_string": {
                            "fields": ["paymentInfos.billingZip"],
                            "query": "10101"
                        }
                    },
                    "path": "paymentInfos"
                }
            }]
        }
    },
    "facets": {},
    "from": 0,
    "size": 25
}'
echo

为什么返回带有账单邮编“20202”的paymentInfos,这正常吗? - Orhan Cinar
@OrhanCinar,您获得的是原始记录的源代码,其中包括所有嵌套字段。 - imotov
我能否仅筛选出邮编为10101的子项,我只需要嵌套字段中的一条记录。这种情况是否可行? - Orhan Cinar
@OrhanCinar 目前还不行。虽然这个功能已经存在(http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/search-request-inner-hits.html),但它尚未被纳入任何发布版本的 Elasticsearch 中。因此,除非您想使用未发布的版本,否则只有在 v1.5 发布时才能实现。 - imotov
谢谢 @imotov,我已经使用了父/子代替。 - Orhan Cinar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接