A combinação elástica deve e não deve

Sep 04 2020

Gostaria de criar uma consulta em elástico onde obtenho todos os documentos que correspondem a um valor e não têm um campo específico: o que estou tentando fazer é o seguinte:

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "some-field.b": true
                    }
                },
                {
                    "bool": {
                        "must_not": {
                            "exists": {
                                "field": "some-other-field.a"
                            }
                        }
                    }
                }
            ]
        }
    }
}

Mesmo se eu alterar um documento em elástico e der um valor para algum-outro-campo. A consulta continua retornando o mesmo número de acertos totais. Alguma ideia de por que isso está acontecendo?

A única maneira que encontrei de mudar isso é adicionando a pontuação mínima à consulta, mas não tenho certeza se realmente entendi o conceito de pontuação. Gostaria de obter os documentos apenas se as duas condições forem atendidas.

Eu percebi outra coisa. Se eu repetir a consulta enquanto tiver uma pontuação mínima, o número de acertos retornados varia.

Respostas

1 ESCoder Sep 04 2020 at 21:41

Uma vez que você não mencionou nada sobre seus dados de mapeamento e índice.

Adicionar um exemplo funcional com mapeamento de índice, dados de índice e consulta de pesquisa (considerando os dados como sendo do tipo aninhado, como se fosse some-other-field.aum campo aninhado)

Mapeamento de índice:

{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" 
      },
      "qualification": {
        "type": "nested" 
      }
    }
  }
}

Dados do índice:

{
  "user" : [ 
    {
      "first" : "Bhavya",
      "last" :  "Gupta"
    }
  ]
}

{
  "user" : [ 
    {
      "first" : "Bhavya",
      "last" :  "Gupta"
    }
  ],
  "qualification": [
    {
      "degree": "MTech"
    }
  ]
}

{
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    }
  ],
  "qualification": [
    {
      "degree": "BTech"
    }
  ]
}

Consulta de pesquisa:

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "user",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "user.first": "Bhavya"
                    }
                  }
                ]
              }
            }
          }
        }
      ],
      "must_not": {
        "nested": {
          "path": "qualification",
          "query": {
            "exists": {
              "field": "qualification.degree"
            }
          }
        }
      }
    }
  }
}

Resultado da pesquisa:

"hits": [
      {
        "_index": "stof",
        "_type": "_doc",
        "_id": "3",
        "_score": 0.35667494,
        "_source": {
          "user": [
            {
              "first": "Bhavya",
              "last": "Gupta"
            }
          ]
        }
      }
    ]
1 Doseikis Sep 10 2020 at 15:24

A última consulta de que precisava era a seguinte:

"query": {
    "bool": {
        "must": [
            {
                "match": {
                    "some-field.b": true
                }
            }
        ],
        "must_not": {
            "nested": {
                "path": "some-other-field",
                "query": {
                    "exists": {
                        "field": "some-other-field.a"
                    }
                }
            }
        }
    }
}

Parece que meu erro foi a parte must_not da consulta, pois o campo some-other-era um campo aninhado