2016-11-16 220 views
1

我正在通过以下文章学习ElasticSearch - https://qbox.io/blog/using-elasticsearch-in-e-commerce-part-1文章。通过运行以下CURL命令创建了用于elasticsearch的索引&类型。如何在PHP的ElasticSearch查询中使用SQL和条件?

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"}' 

字段映射脚本used-

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" 
     } 
    } 
    } 
}' 

我使用PHPto从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

我搜索了很多。但是,无法弄清楚我做错了什么。

回答

2

你需要用在自己的关联数组每个term查询,否则人会被其他覆盖。试试这个查询。

$params = [ 
     'index' => 'ecomercedata', 
     'type' => 'gadgets', 
     'body' => [ 
      'query' => [ 
        'constant_score' => [ 
         'filter' => [ 
          'bool' => [ 
           'must' => [ 
            [ 
            'term' => [ 
             'category' => 'Laptop' 
            ] 
            ], 
            [ 
            'term' => [ 
             'brand' => 'Apple' 
            ] 
            ] 
           ] 
          ] 
         ] 
        ] 
      ] 

     ] 
    ]; 
+0

是的,这是一个工作。有我的错误。感谢您的帮助。 – mi6crazyheart

+0

很高兴帮助! – Val

2

bool总是应该放在query无论它放在哪里。 此外,您的term查询不正确。他们应该在自己的阵列,像这样:

[ 
    'constant_score' => [ 
     'filter' => [ 
      'query' => [ 
       'bool' => [ 
        'must' => [ 
         [ 
          'term' => [ 
           'category' => 'Laptop' 
          ] 
         ], 
         [ 
          'term' => [ 
           'brand' => 'Apple' 
          ] 
         ] 
        ] 
       ] 
      ] 
     ] 
    ] 
] 
+0

你是不是指'''bool'''应该在'''query'''里面? – mi6crazyheart

+0

'constant_score/filter'是旧的方式,但它仍然是正确的。问题是不同的,请参阅其他答案;-) – Val

+0

是的,根据这个文档 - https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_multiple_exact_values.html没关系。 – mi6crazyheart