我试图通过一个简单的示例应用程序来学习elasticsearch,该应用程序列出了与人相关的引用。示例映射可能如下所示:
{
"people" : {
"properties" : {
"name" : { "type" : "string"},
"quotations" : { "type" : "string" }
}
}
}
某些示例数据可能如下所示:
{ "name" : "Mr A",
"quotations" : [ "quotation one, this and that and these"
, "quotation two, those and that"]
}
{ "name" : "Mr B",
"quotations" : [ "quotation three, this and that"
, "quotation four, those and these"]
}
我希望能够在个别引用上使用查询字符串api,并返回匹配的人。例如,我可能想要找到包含(这个和这些)的报价的人 - 这应该返回" A先生"但不是" B"先生等等。我怎样才能做到这一点?
EDIT1:
下面安德烈的回答似乎有效,数据值现在看起来像:
{"name":"Mr A","quotations":[{"value" : "quotation one, this and that and these"}, {"value" : "quotation two, those and that"}]}
但是,我似乎无法使query_string查询生效。以下结果不会产生任何结果:
{
"query": {
"nested": {
"path": "quotations",
"query": {
"query_string": {
"default_field": "quotations",
"query": "quotations.value:this AND these"
}
}
}
}
}
有没有办法让query_string查询使用嵌套对象?
Edit2:是的,请参阅Andrei的回答。
答案 0 :(得分:33)
要实现该要求,您需要查看嵌套对象,而不是查询已展平的值列表,而是查询该嵌套对象中的各个值。例如:
{
"mappings": {
"people": {
"properties": {
"name": {
"type": "string"
},
"quotations": {
"type": "nested",
"properties": {
"value": {
"type": "string"
}
}
}
}
}
}
}
值:
{"name":"Mr A","quotations":[{"value": "quotation one, this and that and these"}, {"value": "quotation two, those and that"}]}
{"name":"Mr B","quotations":[{"value": "quotation three, this and that"}, {"value": "quotation four, those and these"}]}
查询:
{
"query": {
"nested": {
"path": "quotations",
"query": {
"bool": {
"must": [
{ "match": {"quotations.value": "this"}},
{ "match": {"quotations.value": "these"}}
]
}
}
}
}
}
答案 1 :(得分:6)
不幸的是,没有好方法可以做到这一点。 http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/complex-core-fields.html
当您从Elasticsearch获取文档时,任何数组都将在 与索引文档时的顺序相同。 _source字段 你得到的包含与你完全相同的JSON文档 索引。
但是,数组被索引 - 可搜索 - 作为多值字段, 这是无序的。在搜索时你不能参考“第一个 元素“或”最后一个元素“。而是将阵列视为一包 值。
换句话说,它总是在考虑数组中的所有值。
这将只返回A先生
{
"query": {
"match": {
"quotations": {
"query": "quotation one",
"operator": "AND"
}
}
}
}
但这将使A先生和A先生同时回归。 B先生:
{
"query": {
"match": {
"quotations": {
"query": "this these",
"operator": "AND"
}
}
}
}
答案 2 :(得分:0)
如果启用了scripting,这应该可以工作:
"script": {
"inline": "for(element in _source.quotations) { if(element == 'this' && element == 'these') {return true;} }; return false;"
}