【发布时间】:2015-06-17 18:53:47
【问题描述】:
我想搜索不相关的不同字段,它们是对象数组。我不知道怎么做。
鉴于以下映射和数据输入:我想让用户能够以任意组合搜索所有可能的字段。用户将使用带有关键字输入、排除关键字输入、日期范围和多选下拉列表的表单。该查询是什么样的?我在数据条目下方包含了几个失败的查询和过滤器。
映射
{
"plants" : {
"properties" : {
"name" : {"type" : "string"},
"description" : {"type" : "string"},
"planting" : {"type" : "string"},
"maintenance" : {"type" : "string"},
"type" : {"type" : "integer"},
"petals" : {
"properties" : {
"color" : {"type" : "string"}
}
},
"species" : {
"properties" : {
"name" : {"type" : "string"},
"subspecies" : {
"properties" : {
"name" : {"type" : "string"}
}
}
}
},
"pests" : {
"properties" : {
"pest" : {"type" : "string"}
}
},
"diseases" : {
"properties" : {
"disease" : {"type" : "string"}
}
}
}
}
}
数据输入:Rose
{
"name" : "Rose",
"description" : "A few paragraphs of text",
"planting" : "A few paragraphs of text",
"maintenance" : "A few paragraphs of text",
"type" : "Perennial",
"petals" : [
{"color" : "Red"},
{"color" : "White"},
{"color" : "Yellow"},
{"color" : "Pink"},
{"color" : "Orange"},
{"color" : "Purple"}
],
"species" : [
{
"name" : "Hulthemia",
"description" : "A few paragraphs of text",
"subspecies" : []
},
{
"name" : "Hesperrhodos",
"description" : "A few paragraphs of text",
"subspecies" : []
},
{
"name" : "Platyrhodon",
"description" : "A few paragraphs of text",
"subspecies" : []
},
{
"name" : "Rosa",
"description" : "A few paragraphs of text",
"subspecies" : [
{"name" : "Banksianae"},
{"name" : "Bracteatae"},
{"name" : "Caninae"},
{"name" : "Carolinae"},
{"name" : "Chinensis"},
{"name" : "Gallicanae"},
{"name" : "Gymnocarpae"},
{"name" : "Laevigatae"},
{"name" : "Pimpinellifoliae"},
{"name" : "Cinnamomeae"},
{"name" : "Synstylae"}
]
}
],
"pests" : [],
"diseases" : []
}
查询
例如,我在以下查询中取得了成功,但它在 100k 到 10M 数据条目的大型数据集(不是花和许多字段)上并不准确。我正在搜索具有多个精确值匹配的多个字段,同时希望为每个条目提供相关性分数。当我想要“petal.color”为“紫色”、“粉红色”和/或“白色”的花朵以及搜索另外两个字段(如“花瓣”或像“类型”这样的字符串。我可以将“minimum_should_match”设置为等于二,但是具有多个“petal.color”的花朵将满足该要求,并且我将获得不是“多年生”或“年度”的“类型”,例如“双年生”。我研究了过滤器并将其作为我的下一个示例。
{
"query" : {
"bool" : {
"must" : [
{
"multi_match":{
"query":"disease resistant",
"type":"cross_fields",
"fields":[
"description",
"planting",
"maintenance",
"name"
],
"tie_breaker":0.3
}
}
],
"must_not" : [
{
"multi_match":{
"query":"lavender",
"type":"cross_fields",
"fields":[
"description",
"planting",
"maintenance",
"name"
],
"tie_breaker":0.3
}
}
],
"should" : [
{"match" : {"type" : "Perennial"}},
{"match" : {"type" : "Annual"}},
{"match" : {"petals.color" : "purple"}},
{"match" : {"petals.color" : "pink"}},
{"match" : {"petals.color" : "white"}}
]
}
}
}
使用术语查询
以下是使用“条款”的尝试。我不确定为什么它不起作用。
{
"query" : {
"bool" : {
"must" : [
{
"multi_match":{
"query":"disease resistant",
"type":"cross_fields",
"fields":[
"description",
"planting",
"maintenance",
"name"
],
"tie_breaker":0.3
}
},
{
"terms" : {
"type" : ["Perennial","Annual"],
"minimum_should_match" : 1
}
},
{
"terms" : {
"petals.color" : ["purple","pink","white"],
"minimum_should_match" : 1
}
}
],
"must_not" : [
{
"multi_match":{
"query":"lavender",
"type":"cross_fields",
"fields":[
"description",
"planting",
"maintenance",
"name"
],
"tie_breaker":0.3
}
}
],
"should" : [
]
}
}
}
使用查询/过滤器进行查询
以下内容尝试将查询和过滤器结合起来使用和/或过滤器的组合。 我觉得问题出在“或”“petals.color”上,其中“petals.color”是一个颜色列表,而不是一个确切的值。
另一个选项是petals.color的排列列表来解决“或”问题(即紫色+粉色+白色,紫色+粉色,紫色+白色,粉色+白色,紫色,粉色,白色。)那会得到在一个可能有数百个可能值的列表上详尽无遗,并且您正在搜索其中的一个子集。例如国家列表和您匹配的特定大陆的国家。
另一个选项是反向选择“petals.color”并放入“bool”“must_not”。由于 elasticsearch 支持聚合,因此这比排列列表的工作量少。
{
"query" : {
"filtered" : {
"query" : {
"bool" : {
"must" : [
{
"multi_match":{
"query":"disease resistant",
"type":"cross_fields",
"fields":[
"description",
"planting",
"maintenance",
"name"
],
"tie_breaker":0.3
}
}
],
"must_not" : [
{
"multi_match":{
"query":"lavender",
"type":"cross_fields",
"fields":[
"description",
"planting",
"maintenance",
"name"
],
"tie_breaker":0.3
}
}
],
"should" : [
]
}
},
"filter" : {
"and" : [
{
"or" : [
{"match" : {"type" : "Perennial"}},
{"match" : {"type" : "Annual"}}
]
},
{
"or" : [
{"match" : {"petals.color" : "purple"}},
{"match" : {"petals.color" : "pink"}},
{"match" : {"petals.color" : "white"}}
]
}
]
}
}
}
}
【问题讨论】:
标签: elasticsearch