Фильтр Elasticsearch по крайней мере одно из вложенных значений больше нуля - PullRequest
0 голосов
/ 21 октября 2019

У меня следующая структура документа

{
  "_source": {
    "id": 8844,
    "name": {
      "en": "Product A"
    },
    "published": true,

    "variants": [
      {
        "variant_id": 3263,
        "price": "19.500",
        "stock": 2,
        "published": 1,
        "bar_code": "76123xxx"
      },
      {
        "variant_id": 3264,
        "price": "19.500",
        "stock": 0,
        "published": 1,
        "bar_code": "xxxx7049160"
      }

    ]
  }

Как вы можете видеть, есть два варианта для этого продукта, и один вариант отсутствует на складе stock: 0. Я хочу получить этот продукт, если хотя бы один из вариантов имеет запас больше нуля.

Кроме того, я не хочу этот продукт, если запас всех вариантов равен нулю.

На данный момент у меня есть следующие параметры для запроса:

[
    'index' => 'products',
    'body'  => [
        "query" => [
            "terms" => [
                "_id" => $ids, // I pass an array of ids
            ],
            "bool" => [
                    "filter" => [
                    "term" => ["published" => true,]
                ]
            ],
        ],
    ],
];

Как мне решить эту проблему? ,Я используюasticsearch 7, драйвер php. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация

1 Ответ

1 голос
/ 21 октября 2019

Предполагая, что ваше отображение имеет формат ниже, я соответственно предоставил запрос.

Отображение:

PUT my_variants_index
{
  "mappings": {
    "properties": {
      "id":{
        "type": "long"
      },
      "name":{
        "properties": {
          "en":{
            "type":"keyword"
          }
        }
      },
      "published":{
        "type": "boolean"
      },
      "variants":{
        "type": "nested",      <---- Note this as you've mentioned in your question this is of nested type. 
        "properties": {
          "variant_id":{
            "type": "long"
          },
          "price":{
            "type": "float"
          },
          "stock":{
            "type": "long"
          },
          "publishes":{
            "type": "long"
          },
          "bar_code":{
            "type": "keyword"
          }
        }
      }
    }
  }
}

Образцы документов:

Обратите внимание, что документы first(Product A) и third(Product C) имеют по крайней мере одно значение запаса> 0.

POST my_variants_index/_doc/1
{
  "id": "8844",
  "name": {
      "en": "Product A"
    },
    "published": true,

    "variants": [
      {
        "variant_id": 3263,
        "price": "19.500",
        "stock": 2,
        "published": 1,
        "bar_code": "76123xxx"
      },
      {
        "variant_id": 3264,
        "price": "19.500",
        "stock": 0,
        "published": 1,
        "bar_code": "xxxx7049160"
      }
    ]
}

POST my_variants_index/_doc/2
{
  "id": "8855",
  "name": {
      "en": "Product B"
    },
    "published": true,

    "variants": [
      {
        "variant_id": 3263,
        "price": "19.500",
        "stock": 0,
        "published": 1,
        "bar_code": "76123xxx"
      },
      {
        "variant_id": 3264,
        "price": "19.500",
        "stock": 0,
        "published": 1,
        "bar_code": "xxxx7049160"
      }
    ]
}

POST my_variants_index/_doc/3
{
  "id": "8866",
  "name": {
      "en": "Product C"
    },
    "published": true,

    "variants": [
      {
        "variant_id": 3263,
        "price": "19.500",
        "stock": 0,
        "published": 1,
        "bar_code": "76123xxx"
      },
      {
        "variant_id": 3264,
        "price": "19.500",
        "stock": 1,
        "published": 1,
        "bar_code": "xxxx7049160"
      }
    ]
}

Вложенный запрос:

POST my_variants_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "id": [
              "8844",
              "8855",
              "8866"
            ]
          }
        },
        {
          "term": {
            "published": {
              "value": true
            }
          }
        }
      ],
      "filter": {
        "nested": {
          "path": "variants",
          "query": {
            "bool": {
              "must": [
                {
                  "range": {
                    "variants.stock": {
                      "gte": 1
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

Обратите внимание, что я использовал Range Query внутри Nested Query

Ответ:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.1335313,
    "hits" : [
      {
        "_index" : "my_variants_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.1335313,
        "_source" : {
          "id" : "8866",
          "name" : {
            "en" : "Product C"
          },
          "published" : true,
          "variants" : [
            {
              "variant_id" : 3263,
              "price" : "19.500",
              "stock" : 0,
              "published" : 1,
              "bar_code" : "76123xxx"
            },
            {
              "variant_id" : 3264,
              "price" : "19.500",
              "stock" : 1,
              "published" : 1,
              "bar_code" : "xxxx7049160"
            }
          ]
        }
      },
      {
        "_index" : "my_variants_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.1335313,
        "_source" : {
          "id" : "8844",
          "name" : {
            "en" : "Product A"
          },
          "published" : true,
          "variants" : [
            {
              "variant_id" : 3263,
              "price" : "19.500",
              "stock" : 2,
              "published" : 1,
              "bar_code" : "76123xxx"
            },
            {
              "variant_id" : 3264,
              "price" : "19.500",
              "stock" : 0,
              "published" : 1,
              "bar_code" : "xxxx7049160"
            }
          ]
        }
      }
    ]
  }
}

Обратите внимание, что Product A и Product C возвращаются в качестве ответа.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...