我正在通过这篇文章https://qbox.io/blog/using-elasticsearch-in-e-commerce-part-1学习ElasticSearch。指数&通过运行以下CURL命令创建了elasticsearch的类型。
curl -XPOST 'localhost:9200/ecomercedata/gadgets/_bulk?pretty' -d'
{ "index": { "_id": 1 }}
{ "name" : "MacBook Pro", "category" : "Laptop", "brand" : "Apple", "rating" : 9, "prize" : 1299.00, "piecesSold" : 9500, "dateOfRelease" : "2005-02-01"}
{ "index": { "_id": 2 }}
{"name" : "MacBook Air", "category" : "Laptop", "brand" : "Apple", "rating" : 8, "prize" : 1099.00, "piecesSold" : 8700, "dateOfRelease" : "2006-05-01"}
{ "index": { "_id": 3 }}
{"name" : "ATIV Book", "category" : "Laptop", "brand" : "Samsung", "rating" : 8, "prize" : 1899.00, "piecesSold" : 3500, "dateOfRelease" : "2014-05-01"}
{ "index": { "_id": 4 }}
{"name" : "Inspiron", "category" : "Laptop", "brand" : "Dell", "rating" : 6, "prize" : 700.00, "piecesSold" : 4600, "dateOfRelease" : "2008-03-01"}
{ "index": { "_id": 5 }}
{"name" : "Ipad", "category" : "Tablet", "brand" : "Apple", "rating" : 9, "prize" : 600.00, "piecesSold" : 9500 , "dateOfRelease" : "2005-07-01"}
{ "index": { "_id": 6 }}
{"name" : "Galaxy Tab", "category" : "Tablet", "brand" : "Samsung", "rating" : 8, "prize" : 550.00, "piecesSold" : 8500 , "dateOfRelease" : "2007-07-01"}
{ "index": { "_id": 7 }}
{"name" : "Lumia", "category" : "Mobile", "brand" : "Nokia", "rating" : 6, "prize" : 50.00, "piecesSold" : 12000 , "dateOfRelease" : "2009-03-01"}
{ "index": { "_id": 8 }}
{"name" : "Iphone", "category" : "Mobile", "brand" : "Apple", "rating" : 8, "prize" : 60.00, "piecesSold" : 28000 , "dateOfRelease" : "2002-03-01"}
{ "index": { "_id": 9 }}
{"name" : "Xperia", "category" : "Mobile", "brand" : "Sony", "rating" : 8, "prize" : 70.00, "piecesSold" : 24000 , "dateOfRelease" : "2004-03-01"}'
使用字段映射脚本 -
curl -X PUT "http://localhost:9200/ecomercedata/gadgets/_mapping" -d '{
"gadgets" : {
"properties" : {
"category" : {
"type" : "String",
"index" : "not_analyzed"
},
"brand" : {
"type" : "String",
"index" : "not_analyzed"
},
"name" : {
"type" : "String"
},
"rating" : {
"type" : "Integer"
},
"dateOfRelease" : {
"type" : "date",
"format" : "YYYY-mm-dd"
},
"prize" : {
"type" : "Double"
},
"piecesSold" : {
"type" : "Integer"
}
}
}
}'
我正在使用PHP从ElasticSearch获取记录。这是我的PHP脚本。
<?php
require 'vendor/autoload.php';
$hosts = [
'http://localhost:9200', // SSL to localhost
];
$client = Elasticsearch\ClientBuilder::create() // Instantiate a new ClientBuilder
->setHosts($hosts) // Set the hosts
->build();
$params = [
'index' => 'ecomercedata',
'type' => 'gadgets',
'body' => [
'query' => [
'constant_score' => [
'filter' => [
'bool' => [
'must' => [
'term' => [
'category' => 'Laptop'
],
'term' => [
'brand' => 'Apple'
]
]
]
]
]
]
]
];
try {
$results = $client->search($params);
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
exit;
}
echo '<pre>';
print_r($results);
echo '</pre>';
?>
基本上,我正在尝试提取category=laptop and brand=Apple
的所有记录。但是,它没有给我一个正确数量的记录。根据输入的数据集,我应该得到2条记录,但我得到4条记录。似乎category and brand
条件的作用类似于OR
而不是AND
。
我google了很多。但是,无法弄清楚我做错了什么。
答案 0 :(得分:2)
bool
应始终包含在query
的任何位置。
此外,您的term
查询不正确。它们应该在它们自己的数组中,如下所示:
[
'constant_score' => [
'filter' => [
'query' => [
'bool' => [
'must' => [
[
'term' => [
'category' => 'Laptop'
]
],
[
'term' => [
'brand' => 'Apple'
]
]
]
]
]
]
]
]
答案 1 :(得分:2)
您需要将每个term
查询包装在自己的关联数组中,否则会被另一个查询覆盖。请改为尝试此查询。
$params = [
'index' => 'ecomercedata',
'type' => 'gadgets',
'body' => [
'query' => [
'constant_score' => [
'filter' => [
'bool' => [
'must' => [
[
'term' => [
'category' => 'Laptop'
]
],
[
'term' => [
'brand' => 'Apple'
]
]
]
]
]
]
]
]
];