【问题标题】:How to use SQL AND condition in ElasticSearch query in PHP?如何在 PHP 的 ElasticSearch 查询中使用 SQL AND 条件?
【发布时间】:2016-11-16 14:58:43
【问题描述】:

我正在通过以下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

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

【问题讨论】:

    标签: php elasticsearch


    【解决方案1】:

    您需要将每个term 查询包装在其自己的关联数组中,否则其中一个会被另一个覆盖。试试这个查询。

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

    【讨论】:

    • 是的,这个正在工作。明白我的错误了。感谢您的帮助。
    • 很高兴它有帮助!
    【解决方案2】:

    bool 应始终包裹在 query 中,无论它放在哪里。 此外,您的term 查询不正确。它们应该在自己的数组中,如下所示:

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

    【讨论】:

    猜你喜欢
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 2014-06-13
    • 2018-08-04
    • 2016-05-09
    • 2021-09-18
    相关资源
    最近更新 更多