Erstellen Sie eine Elasticsearch-Curl-Abfrage für nicht null und nicht leer ("").


73

Wie kann ich eine Elasticsearch-Curl-Abfrage erstellen, um den Feldwert zu erhalten, der nicht null und nicht leer ist ("")?

Hier ist die MySQL-Abfrage:

select field1 from mytable where field1!=null and field1!="";

4
Alle elastischen Fragen sollten die Version von Elastic haben, die Sie verwenden. Es ist obligatorisch, weil selbst die Nebenversionen so viele Änderungen haben
Henley Chiu

Antworten:


76

Ein Nullwert und eine leere Zeichenfolge führen dazu, dass kein Wert indiziert wird. In diesem Fall können Sie den existsFilter verwenden

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "constant_score" : {
         "filter" : {
            "exists" : {
               "field" : "myfield"
            }
         }
      }
   }
}
'

Oder in Kombination mit (zB) einer Volltextsuche auf dem titleFeld:

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "filtered" : {
         "filter" : {
            "exists" : {
               "field" : "myfield"
            }
         },
         "query" : {
            "match" : {
               "title" : "search keywords"
            }
         }
      }
   }
}
'

Hallo, ich möchte nur wissen, wie ich es für mehrere Felder tun kann. :)
Uttam Palkar

1
wickle nur mehrere existsFilter in einem andFilter elasticsearch.org/guide/reference/query-dsl/and-filter.html
DrTech

Es ist nicht erforderlich, den Filter mit einer Abfrage zu versehen.
WhatIsHeDoing

29
Dies filtert keine leeren Zeichenfolgen heraus. An empty string is a non-null value.- elastic.co/guide/en/elasticsearch/reference/current/…
Luqmaan

Beachten Sie die bequeme einzeilige Curl-XGET ' 127.0.0.1:9200/test/test/_search?q=_exists_:field1 '
Rene Wooller

27

Wickeln Sie einen fehlenden Filter in den Abschnitt "Muss nicht" eines Bool-Filters ein . Es werden nur Dokumente zurückgegeben, in denen das Feld vorhanden ist. Wenn Sie die Eigenschaft "null_value" auf "true" setzen, sind Werte explizit nicht null.

{
  "query":{
     "filtered":{
        "query":{
           "match_all":{}
        },
        "filter":{
            "bool":{
              "must":{},
              "should":{},
              "must_not":{
                 "missing":{
                    "field":"field1",
                    "existence":true,
                    "null_value":true
                 }
              }
           }
        }
     }
  }
}

1
Hurr ... hat den Exists-Filter vergessen. Verwenden Sie die Lösung von DrTech. Meine ist eine weniger elegante Methode, um dasselbe zu tun.
Zach

Huzzah! Sie haben gerade vier Stunden Elend beendet. Danke :)
Simonmorley

Dieser Ansatz funktionierte für mich in v1.0.3, funktioniert aber nicht mehr in v1.5
phirschybar

@Zach Glaubst du, du könntest mir zufällig bei stackoverflow.com/questions/33630013/… helfen ?
BentCoder

1
Dies war sehr hilfreich und funktionierte gut als Notlösung, da Exits nicht in der von uns verwendeten Version von Elasticsearch enthalten sind. Danke @zach
rubyisbeautiful

27

Wie @luqmaan in den Kommentaren hervorhob, heißt es in der Dokumentation , dass der Filter exists keine leeren Zeichenfolgen herausfiltert, da diese als Nicht-Null-Werte betrachtet werden .

Wenn Sie also zur Antwort von @ DrTech hinzufügen, um null und leere Zeichenfolgenwerte effektiv herauszufiltern, sollten Sie Folgendes verwenden:

{
    "query" : {
        "constant_score" : {
            "filter" : {
                "bool": {
                    "must": {"exists": {"field": "<your_field_name_here>"}},
                    "must_not": {"term": {"<your_field_name_here>": ""}}
                }
            }
        }
    }
}

26

In elasticsearch 5.6 muss ich den folgenden Befehl verwenden, um leere Zeichenfolgen herauszufiltern:

    GET /_search
    {
        "query" : {
            "regexp":{
                "<your_field_name_here>": ".+"
            }
        }
    }  

1
Leider ja, das ist die einzige Lösung, die ich auch gefunden habe ... sehr seltsam, es gibt keine einfache Abfrage, um field = '' ...
danvasiloiu

2
Regex ist nicht die beste Leistung. check stackoverflow.com/questions/25561981/…
danvasiloiu

Dies ist die einzige Lösung, die für Felder funktioniert, für die "Felddaten" nicht aktiviert sind, danke
Ron Serruya,

8

Sie können dies mit einer Bool-Abfrage und einer Kombination aus must und must_not wie folgt tun:

GET index/_search
{
    "query": {
        "bool": {
            "must": [
                {"exists": {"field": "field1"}}
            ],
            "must_not": [
                {"term": {"field1": ""}}
            ]
        }
    }
}

Ich habe dies mit Elasticsearch 5.6.5 in Kibana getestet.


6

Sie können nicht über fehlende Filter filtern .

"query": {
  "filtered": {
     "query": {
        "match_all": {}
     },
     "filter": {
        "not": {
           "filter": {
              "missing": {
                 "field": "searchField"
              }
           }
        }
     }
  }
}

Ich konnte eine fehlende Abfrage zum Laufen bringen, habe aber weiterhin "existiert" für ein Array verwendet, um festzustellen, ob ich einen Wert vom Typ "nicht null" finden konnte und er nicht funktionierte. Das war die richtige Lösung für mich. Vielen Dank!
James Drinkard

6

Die einzige Lösung, die in 5.6.5 für mich funktioniert hat, war die Regex-Antwort von bigstone1998. Ich würde es jedoch aus Leistungsgründen vorziehen, keine Regex-Suche zu verwenden. Ich glaube, der Grund, warum die anderen Lösungen nicht funktionieren, ist, dass ein Standardfeld analysiert wird und daher kein leeres String-Token zum Negieren vorhanden ist. Die vorhandene Abfrage allein hilft auch nicht weiter, da eine leere Zeichenfolge als nicht null betrachtet wird.

Wenn Sie den Index nicht ändern können, ist der Regex-Ansatz möglicherweise Ihre einzige Option. Wenn Sie jedoch den Index ändern können, wird das Problem durch Hinzufügen eines Schlüsselwort-Unterfelds behoben.

In den Zuordnungen für den Index:

"myfield": {
    "type": "text",
    "fields": {
        "keyword": {
            "ignore_above": 256,
            "type": "keyword"
        }
    }
}

Dann können Sie einfach die Abfrage verwenden:

{
  "query": {
    "bool": {
      "must": {
        "exists": {
          "field": "myfield"
        }
      },
      "must_not": {
        "term": {
          "myfield.keyword": ""
        }
      }
    }
  }
}

Beachten Sie die .keywordKomponente must_not.


Dies funktioniert nicht für type=textFelder. Kann aber durch Erweitern des ES-Schemas behoben werden"myfield": { "type": "text", fielddata: true, "fields": { "keyword": { "type": "keyword" } } }
James McGuigan

Warum müssen wir das benutzen .keyword? Hat es etwas mit dem analysierten Feld zu tun, da must_notes genau übereinstimmt? Wenn ja, wenn wir nicht verwenden, .keywordwas bedeutet das? Übrigens, mit .keywordArbeiten für mich.
Luyang Du

1
@LuyangDu Das Schema definiert zwei Felder, myfield und myfield.keyword. Das Feld "myfield.keyword" ist ein explizites "keyword" -Feld, das maximal 256 Zeichen enthält und nur für die genaue Übereinstimmung verwendet wird, im Vergleich zu "myfield", einem offenen Textfeld, auf das Tokenizer und andere Verarbeitungen angewendet werden können. Diese beiden Felder funktionieren daher sehr unterschiedlich und nur das Schlüsselwortfeld stellt sowohl Null- als auch leere Zeichenfolgen als leere Zeichenfolge dar, sodass Sie negieren können, wenn dieses Feld leer ist.
LaserJesus

1

Wir verwenden Elasticsearch Version 1.6 und ich habe diese Abfrage eines Kollegen verwendet, um nicht null und nicht leer für ein Feld abzudecken:

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "bool": {
          "must": [
            {
              "exists": {
                "field": "myfieldName"
              }
            },
            {
              "not": {
                "filter": {
                  "term": {
                    "myfieldName": ""
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}

Vielen Dank, dass Sie meinen Tag gerettet haben
Igor Beaufils

1

Hier ist das Abfragebeispiel, um das Vorhandensein mehrerer Felder zu überprüfen:

{
  "query": {
    "bool": {
      "filter": [
        {
          "exists": {
            "field": "field_1"
          }
        },
        {
          "exists": {
            "field": "field_2"
          }
        },
        {
          "exists": {
            "field": "field_n"
          }
        }
      ]
    }
  }
}


0

Sie können eine Bool-Kombinationsabfrage mit must / must_not verwenden, die eine hervorragende Leistung bietet und alle Datensätze zurückgibt, bei denen das Feld nicht null und nicht leer ist.

bool must_not ist wie "NOT AND", was Feld bedeutet! = "", bool muss existieren, bedeutet its! = null.

so effektiv aktivieren: wobei field1! = null und field1! = ""

GET  IndexName/IndexType/_search
{
    "query": {
        "bool": {
            "must": [{
                "bool": {
                    "must_not": [{
                        "term": { "YourFieldName": ""}
                    }]
                }
            }, {
                "bool": {
                    "must": [{
                      "exists" : { "field" : "YourFieldName" }
                    }]
                }
            }]
        }   
    }
}

ElasticSearch Version:

  "version": {
    "number": "5.6.10",
    "lucene_version": "6.6.1"
  }

0

Sie müssen die Bool-Abfrage mit must / must_not verwenden und sind vorhanden

Um herauszufinden, wo der Ort null ist

{
  "query": {
    "bool": {
      "must_not": {
        "exists": {
          "field": "place"
        }
      }
    }
  }
}

Um dorthin zu gelangen, ist der Ort nicht null

{
  "query": {
    "bool": {
      "must": {
        "exists": {
          "field": "place"
        }
      }
    }
  }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.