To, czego szukasz, to multi-match query, ale nie działa tak, jak byś chciał.
Porównaj wyjście validate dla multi_match
i query_string
.
multi_match
(z operatorem and
) będzie upewnić się, że wszystkie terminy występują w co najmniej jednej dziedzinie:
curl -XGET 'http://127.0.0.1:9200/_validate/query?pretty=1&explain=true' -d '
{
"multi_match" : {
"operator" : "and",
"fields" : [
"firstname",
"lastname"
],
"query" : "john smith"
}
}
'
# {
# "_shards" : {
# "failed" : 0,
# "successful" : 1,
# "total" : 1
# },
# "explanations" : [
# {
# "index" : "test",
# "explanation" : "((+lastname:john +lastname:smith) | (+firstname:john +firstname:smith))",
# "valid" : true
# }
# ],
# "valid" : true
# }
Podczas query_string
(z default_operator AND
) sprawdzi, że każdy termin występuje w co najmniej jednej dziedzinie:
curl -XGET 'http://127.0.0.1:9200/_validate/query?pretty=1&explain=true' -d '
{
"query_string" : {
"fields" : [
"firstname",
"lastname"
],
"query" : "john smith",
"default_operator" : "AND"
}
}
'
# {
# "_shards" : {
# "failed" : 0,
# "successful" : 1,
# "total" : 1
# },
# "explanations" : [
# {
# "index" : "test",
# "explanation" : "+(firstname:john | lastname:john) +(firstname:smith | lastname:smith)",
# "valid" : true
# }
# ],
# "valid" : true
# }
więc masz kilka opcji, aby osiągnąć to, czego po:
Preparse terminy wyszukiwania, aby usunąć rzeczy jak symboli wieloznacznych, itp, przed użyciem query_string
Preparse warunki wyszukiwania, aby wyodrębnić każde słowo, a następnie wygenerować multi_match
zapytania za słowem
Korzystanie index_name
w twojej mapowanie pól nazw w celu indeksowania ich danych w jednym polu, które następnie można wykorzystać do wyszukiwania. (Podobnie jak swój własny all
dziedzinie):
W następujący sposób:
curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1' -d '
{
"mappings" : {
"test" : {
"properties" : {
"firstname" : {
"index_name" : "name",
"type" : "string"
},
"lastname" : {
"index_name" : "name",
"type" : "string"
}
}
}
}
}
'
curl -XPOST 'http://127.0.0.1:9200/test/test?pretty=1' -d '
{
"firstname" : "john",
"lastname" : "smith"
}
'
curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1' -d '
{
"query" : {
"match" : {
"name" : {
"operator" : "and",
"query" : "john smith"
}
}
}
}
'
# {
# "hits" : {
# "hits" : [
# {
# "_source" : {
# "firstname" : "john",
# "lastname" : "smith"
# },
# "_score" : 0.2712221,
# "_index" : "test",
# "_id" : "VJFU_RWbRNaeHF9wNM8fRA",
# "_type" : "test"
# }
# ],
# "max_score" : 0.2712221,
# "total" : 1
# },
# "timed_out" : false,
# "_shards" : {
# "failed" : 0,
# "successful" : 5,
# "total" : 5
# },
# "took" : 33
# }
Uwaga jednak, że firstname
i lastname
już przeszukiwać niezależnie. Dane dla obu pól zostały zindeksowane na name
.
Można użyć multi-fields z parametrem path
aby je przeszukiwać zarówno samodzielnie i razem, w następujący sposób:
curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1' -d '
{
"mappings" : {
"test" : {
"properties" : {
"firstname" : {
"fields" : {
"firstname" : {
"type" : "string"
},
"any_name" : {
"type" : "string"
}
},
"path" : "just_name",
"type" : "multi_field"
},
"lastname" : {
"fields" : {
"any_name" : {
"type" : "string"
},
"lastname" : {
"type" : "string"
}
},
"path" : "just_name",
"type" : "multi_field"
}
}
}
}
}
'
curl -XPOST 'http://127.0.0.1:9200/test/test?pretty=1' -d '
{
"firstname" : "john",
"lastname" : "smith"
}
'
Przeszukiwanie pole any_name
działa:
curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1' -d '
{
"query" : {
"match" : {
"any_name" : {
"operator" : "and",
"query" : "john smith"
}
}
}
}
'
# {
# "hits" : {
# "hits" : [
# {
# "_source" : {
# "firstname" : "john",
# "lastname" : "smith"
# },
# "_score" : 0.2712221,
# "_index" : "test",
# "_id" : "Xf9qqKt0TpCuyLWioNh-iQ",
# "_type" : "test"
# }
# ],
# "max_score" : 0.2712221,
# "total" : 1
# },
# "timed_out" : false,
# "_shards" : {
# "failed" : 0,
# "successful" : 5,
# "total" : 5
# },
# "took" : 11
# }
wyszukiwania firstname
dla john AND smith
robi” t pracy:
curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1' -d '
{
"query" : {
"match" : {
"firstname" : {
"operator" : "and",
"query" : "john smith"
}
}
}
}
'
# {
# "hits" : {
# "hits" : [],
# "max_score" : null,
# "total" : 0
# },
# "timed_out" : false,
# "_shards" : {
# "failed" : 0,
# "successful" : 5,
# "total" : 5
# },
# "took" : 2
# }
Ale szukając firstname
tylko dla john
działa poprawnie:
curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1' -d '
{
"query" : {
"match" : {
"firstname" : {
"operator" : "and",
"query" : "john"
}
}
}
}
'
# {
# "hits" : {
# "hits" : [
# {
# "_source" : {
# "firstname" : "john",
# "lastname" : "smith"
# },
# "_score" : 0.30685282,
# "_index" : "test",
# "_id" : "Xf9qqKt0TpCuyLWioNh-iQ",
# "_type" : "test"
# }
# ],
# "max_score" : 0.30685282,
# "total" : 1
# },
# "timed_out" : false,
# "_shards" : {
# "failed" : 0,
# "successful" : 5,
# "total" : 5
# },
# "took" : 3
# }
Ciągle przychodzę do tego pytania w kółko. Świetne, wiecznie zielone pytanie! –