Можно ли отфильтровать совпадению со всеми вложенными сущностями?

Добрый день.
Хочу фильтрануть выборку так что бы ВСЕ nested объекты подпадали под запрос.
Пример:

    [
          {
            "_index" : "test-profiles",
            "_type" : "_doc",
            "_id" : "n4fP33QBtwtcEcs-Y29P",
            "_score" : 1.3254224,
            "_source" : {
              "name" : "3 profile dody",
              "grop_criteria" : [
                {
                  "a" : 5,
                  "b" : false,
                  "c" : "asd"
                }
              ]
            }
          },
          {
            "_index" : "test-profiles",
            "_type" : "_doc",
            "_id" : "oYfR33QBtwtcEcs-A2-E",
            "_score" : 1.3254224,
            "_source" : {
              "name" : "3 profile dody",
              "grop_criteria" : [
                {
                  "a" : 5,
                  "b" : false,
                  "c" : "asd"
                },
                {
                  "a" : 1,
                  "b" : true,
                  "c" : "dsa"
                }
              ]
            }
          }
        ]

Хочу a>2 и c=asd
"n4fP33QBtwtcEcs-Y29P" попадет в выборку
"oYfR33QBtwtcEcs-A2-E" не должен

А если grop_criteria - пустое?

тоже попадает в выборку)

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

Есть такой трюк. Вместо того, чтобы сразу искать нужные документы, мы начнем, с нахождения всех ненужных документов - то есть документов, в которых есть хотябы один вложенный объект, в котором a <= 2 или c != asd. А потом мы этот список инвертируем - то есть оставим только документы, которые не вошли в этот список:

DELETE test

PUT test
{
  "mappings": {
    "properties": {
      "grop_criteria": {
        "type": "nested",
        "properties": {
          "c": {
            "type": "keyword"
          }
        }
      }
    }
  }
}


PUT test/_bulk
{"index":{"_id": "n4fP33QBtwtcEcs-Y29P"}}
{"name":"3 profile dody","grop_criteria":[{"a":5,"b":false,"c":"asd"}]}
{"index":{"_id": "oYfR33QBtwtcEcs-A2-E"}}
{"name":"3 profile dody","grop_criteria":[{"a":5,"b":false,"c":"asd"},{"a":1,"b":true,"c":"dsa"}]}    
{"index":{"_id": "empty_criteria"}}
{"name":"3 profile dody"}    
{"index":{"_id": "totatly_off"}}
{"name":"3 profile dody","grop_criteria":[{"a":-5,"b":false,"c":"xyz"}]}    
{"index":{"_id": "all_good"}}
{"name":"3 profile dody","grop_criteria":[{"a":10,"b":false,"c":"asd"}, {"a":12,"b":false,"c":"asd"}]}    



GET test/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "nested": {
            "path": "grop_criteria",
            "query": {
              "bool": {
                "should": [
                  {
                    "range": {
                      "grop_criteria.a": {
                        "lte": 2
                      }
                    }
                  },
                  {
                    "bool": {
                      "must_not": [
                        {
                          "term": {
                            "grop_criteria.c": {
                              "value": "asd"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
1 Like

Спасибо!
Очень похоже на рабочий вариант.
В плане читабельности, запросы в инверсии будут прихрамывать, конечно.
Очень надеялся что в эластике есть какой-то встроенный механизм для магии такого рода.

Упрощенный вариант без инверсии запросов:

GET test/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "nested": {
            "path": "grop_criteria",
            "query": {
              "bool": {
                "must_not": [
                  {
                    "range": {
                      "grop_criteria.a": {
                        "gt": 2
                      }
                    }
                  },
                  {
                    "term": {
                      "grop_criteria.c": {
                        "value": "asd"
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
1 Like