Reputation: 111
I have products with attributes. For example "name", "brand", "color", "category", "size". When I'm searching products by phrase (for example "black jacket puma"), besides exact match with "brand" = "puma", "color" = "black", "category" = "jacket" or "name" = "Black puma jacket", I have also products with a partial match. My query is:
'match' => [
'message' => [
'query' => "black puma jacket"
'operator' => 'and'
]
]
I also tried this query:
'multi_match' => [
'fields' => [
'brand',
'color',
'name'
],
'query' => 'puma black jacket',
]
What's wrong with my query?
UPD:
My mappings:
'brand' => [
'type' => 'string',
'fields' => [
'keyword' => [
'type' => 'string',
'analyzer' => 'slug',
'index_options' => 'docs',
],
'raw' => [
'type' => 'string',
'analyzer' => 'format',
]
]
],
'color' => [
'type' => 'string',
'fields' => [
'keyword' => [
'type' => 'string',
'analyzer' => 'slug',
'index_options' => 'docs',
],
'raw' => [
'type' => 'string',
'analyzer' => 'format',
]
]
],
'category' => [
'type' => 'string',
'fields' => [
'keyword' => [
'type' => 'string',
'analyzer' => 'slug',
'index_options' => 'docs',
],
'raw' => [
'type' => 'string',
'analyzer' => 'format',
]
]
],
'category_id' => [
'type' => 'integer',
],
'store_id' => [
'type' => 'integer',
],
'size' => [
'type' => 'string',
'fields' => [
'keyword' => [
'type' => 'string',
'analyzer' => 'slug',
'index_options' => 'docs',
],
'raw' => [
'type' => 'string',
'analyzer' => 'format',
]
]
],
'material' => [
'type' => 'string',
'fields' => [
'keyword' => [
'type' => 'string',
'analyzer' => 'slug',
'index_options' => 'docs',
],
'raw' => [
'type' => 'string',
'analyzer' => 'format',
]
]
],
'type' => [
'type' => 'string',
'fields' => [
'keyword' => [
'type' => 'string',
'analyzer' => 'slug',
'index_options' => 'docs',
],
'raw' => [
'type' => 'string',
'analyzer' => 'format',
]
]
],
'volume' => [
'type' => 'string',
'fields' => [
'keyword' => [
'type' => 'string',
'analyzer' => 'slug',
'index_options' => 'docs',
],
'raw' => [
'type' => 'string',
'analyzer' => 'format',
]
]
],
'price' => [
'type' => 'float',
],
'desc' => [
'type' => 'string',
],
'sku' => [
'type' => 'string',
'index' => 'not_analyzed'
],
'picture' => [
'type' => 'string',
'index' => 'not_analyzed'
]
];
Upvotes: 0
Views: 293
Reputation: 2993
Base on your mappings and requirements i think cross_fields might help you.
Example with only 2 properties (color and category):
Post a few documents:
POST my_index/_doc/1
{
"color": "black",
"category": "1"
}
POST my_index/_doc/2
{
"color": "black",
"category": "2"
}
POST my_index/_doc/3
{
"color": "black",
"category": "3"
}
POST my_index/_doc/4
{
"color": "1",
"category": "jacket"
}
POST my_index/_doc/5
{
"color": "2",
"category": "jacket"
}
POST my_index/_doc/6
{
"color": "3",
"category": "jacket"
}
POST my_index/_doc/6
{
"color": "3",
"category": "jacket"
}
POST my_index/_doc/7
{
"color": "black",
"category": "jacket"
}
POST my_index/_doc/8
{
"color": "black",
"category": "jacket"
}
Your search query will look like:
GET my_index/_search
{
"query": {
"multi_match": {
"query": "black jacket",
"fields": [],
"type": "cross_fields",
"operator": "and",
"analyzer": "standard"
}
}
}
Results:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : 1.2192403,
"hits" : [
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "7",
"_score" : 1.2192403,
"_source" : {
"color" : "black",
"category" : "jacket"
}
},
{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "8",
"_score" : 1.2192403,
"_source" : {
"color" : "black",
"category" : "jacket"
}
}
]
}
As you can see we didn't get all other document with partial match of black or jacket
Hope this help
Upvotes: 1
Reputation: 749
According to your requirement, I would group brand, color & category into one field and then apply phrase match. You need to modify products mapping
PUT /products
{
"mappings":{
"properties":{
"brand": {
"type": "text",
"copy_to": "name",
...
},
"color": {
"type": "text",
"copy_to": "name",
...
},
"category": {
"type": "text",
"copy_to": "name",
...
},
"name": {
"type": "text"
},
...
}
}
}
Search using phrase match on name field
GET /products/_search
{
"query":{
"match_phrase": {
"name": {
"query": {
"name": "black puma jacket",
"slop": 1
}
}
}
}
}
Upvotes: 0