2013-03-21 6 views

Antwort

36

Ich würde mir die script filter ansehen. Der folgende Filter sollte nur die Dokumente zurückgeben, die mindestens 10 Elemente im Feld fieldname enthalten, das ein Array ist. Beachten Sie, dass dies je nach Anzahl der Dokumente in Ihrem Index teuer sein kann.

"filter" : { 
    "script" : { 
     "script" : "doc['fieldname'].values.length > 10" 
    } 
} 

In Bezug auf die zweite Frage: Haben Sie wirklich eine leere Array dort? Oder ist es nur ein Array-Feld ohne Wert? Sie können die missing filter zu bekommen Dokumente verwenden, die keinen Wert für ein bestimmtes Feld haben:

"filter" : { 
    "missing" : { "field" : "user" } 
} 

Ansonsten denke ich Sie Scripting wieder verwenden müssen, ähnlich zu dem, was ich oben angedeutet, nur mit einer anderen Länge als Eingabe. Wenn die Länge konstant ist würde ich es in der params Abschnitt gelegt, so dass das Skript durch Elasticsearch und erneut verwendet werden zwischengespeichert werden, da es immer das gleiche:

"filter" : { 
    "script" : { 
     "script" : "doc['fieldname'].values.length > param1" 
     "params" : { 
      "param1" : 10 
     } 
    } 
} 
+0

würden Sie wissen, wie dies zu tun wäre, wenn das Feld eine Zeichenfolge und kein Array wäre? Ich habe versucht "" Skript ":" doc ['title']. value.length()> 10 "' aber kein Glück ... –

+1

Ich habe das gleiche Problem, das Feld ist ein Array, aber ES sieht es als String, so dass es 'groovy.lang.MissingPropertyException wirft: Nein solche Eigenschaft: Länge für die Klasse: java.lang.String' – lisak

+0

@lisak Versuchen Sie Folgendes:" Skript ":" doc ['Feldname']. Größe()> 50 " –

6

Imho die richtige Art und Weise der Filterarrays nach Größe Scripting ist:

"filter" : { 
    "script" : { 
     "script" : "_source.fieldName.size() > 1" 
    } 
} 

Wenn ich das als @javanna es Ausnahme groovy.lang.MissingPropertyException: No such property: length for class: java.lang.String

+2

Quelle ist viel langsamer als doc, sie trifft auf die Festplatte. – whitfin

+0

Beachten Sie auch, dass Sie 'fieldName' und die anderen' fieldname' verwendet haben. – whitfin

+1

Der Grund ist, dass 'Groovy'' size() 'für Arrays und Strings liefert. Wenn nicht alle Ihre Werte Arrays sind, werden Sie auf das Problem stoßen, dass Sie ausgeführt haben, weil Sie versuchen, eine Länge _property_ für einen String zu verwenden, der nicht existiert. – pickypg

10

javanna Antwort ist richtig auf Elasticsearch 1.3.x und früher, seit 1.4 das Standard-Skriptmodul groovy geändert hat (war mvel) .

Um die Frage von OP zu beantworten.

Auf Elasticsearch 1.3.x und früher, verwenden Sie diesen Code:

"filter" : { 
    "script" : { 
     "script" : "doc['fieldname'].values.length > 10" 
    } 
} 

Auf Elasticsearch 1.4.x und später verwenden Sie diesen Code:

"filter" : { 
    "script" : { 
     "script" : "doc['fieldname'].values.size() > 10" 
    } 
} 

Zusätzlich auf Elasticsearch 1.4.3 und Später müssen Sie das dynamische Skripting aktivieren, da es aufgrund eines Sicherheitsproblems standardmäßig deaktiviert ist. Siehe: https://www.elastic.co/guide/en/elasticsearch/reference/1.4/modules-scripting.html

2

Der einfachste Weg, dies zu tun ist, Ihre Daten "denormalisieren", so dass Sie eine Eigenschaft haben, die die Anzahl und einen Boolean enthält, wenn es existiert oder nicht. Dann können Sie nur nach diesen Eigenschaften suchen.

Zum Beispiel:

{ 
    "id": 31939, 
    "hasAttachments": true, 
    "attachmentCount": 2, 
    "attachments": [ 
     { 
     "type": "Attachment", 
     "name": "txt.txt", 
     "mimeType": "text/plain" 
     }, 
     { 
     "type": "Inline", 
     "name": "jpg.jpg", 
     "mimeType": "image/jpeg" 
     } 
    ] 
} 
1

Noch Entsendung für hier, die mit mir gleiche Situation stecken. Lassen Sie uns sagen, dass Ihre Daten wie folgt aussehen:

{ 
    "_source": { 
     "fieldName" : [ 
      { 
       "f1": "value 11", 
       "f2": "value 21" 
      }, 
      { 
       "f1": "value 12", 
       "f2": "value 22" 
      } 
     ] 
    } 
} 

Dann mit Länge filtern fieldName> 1 zum Beispiel:

"query": { 
    "bool" : { 
     "must" : { 
      "script" : { 
       "script" : { 
        "inline": "doc['fieldName.f1'].values.length > 1", 
        "lang": "painless" 
       } 
      } 
     } 
    } 
} 

Das Skript Syntax ist wie ES 5.4 Dokumentation https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html.

Verwandte Themen