2013-03-21 17 views

risposta

36

Vorrei dare un'occhiata allo script filter. Il seguente filtro dovrebbe restituire solo i documenti che hanno almeno 10 elementi nel campo fieldname, che è una matrice. Tieni presente che potrebbe essere costoso a seconda del numero di documenti presenti nel tuo indice.

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

Per quanto riguarda la seconda domanda: hai davvero un array vuoto lì? O è solo un campo array senza valore? È possibile utilizzare il missing filter per ottenere documenti che non hanno alcun valore per un campo specifico:

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

Altrimenti immagino è necessario utilizzare script di nuovo, in modo simile a quello che ho suggerito sopra, solo con una lunghezza diversa come input. Se la lunghezza è costante avevo messo nella sezione params modo che lo script viene memorizzato nella cache da elasticsearch e riutilizzato, poiché è sempre la stessa:

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

Sapresti come fare se il campo fosse una stringa e non un array? ho provato "script": "doc ['title']. value.length()> 10" 'ma senza fortuna ... –

+1

Ho lo stesso problema, il campo è un array, ma ES lo vede come String, in modo che getti 'groovy.lang.MissingPropertyException: Nessuna proprietà di questo tipo: lunghezza per la classe: java.lang.String' – lisak

+0

@lisak Prova questo:" script ":" doc ['nomecampo']. size()> 50 " –

6

Imho il modo corretto di matrici filtranti per dimensione utilizzando scripting è:

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

Se lo faccio come suggerisce @javanna esso genera un'eccezione groovy.lang.MissingPropertyException: No such property: length for class: java.lang.String

+2

La fonte è molto più lenta di doc, colpisce il disco. – whitfin

+0

Inoltre, si noti che hai usato 'fieldName' e gli altri hanno usato' nomecampo'. – whitfin

+1

Il motivo è che 'Groovy' fornisce' size() 'per entrambi gli array e le stringhe. Se non tutti i tuoi valori sono array, allora ti imbatterai nel problema che hai fatto perché stai provando ad usare una lunghezza _property_ su una stringa, che non esiste. – pickypg

10

di javanna è corretta sul elasticsearch 1.3.x e versioni precedenti, dal momento che 1.4 il modulo di script predefinito è cambiato groovy (era mvel) .

Per rispondere alla domanda dell'OP.

Su elasticsearch 1.3.x e versioni precedenti, utilizzare questo codice:

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

Su elasticsearch 1.4.xe più tardi, di questo codice:

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

Inoltre, sulla elasticsearch 1.4.3 e in seguito, sarà necessario abilitare lo script dinamico in quanto è stato disabilitato per impostazione predefinita, a causa di problemi di sicurezza. Vedi: https://www.elastic.co/guide/en/elasticsearch/reference/1.4/modules-scripting.html

2

Il modo più semplice per farlo è quello di "denormalizzare" i dati in modo da avere una proprietà che contenga il conteggio e un valore booleano se esiste o meno. Quindi puoi semplicemente cercare su quelle proprietà.

Ad esempio:

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

Ancora distacco a qui per chi bloccati stessa situazione con me. Diciamo che i dati simile a questa:

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

Poi per filtrare fieldName con lunghezza> 1 per esempio:

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

La sintassi script è il ES 5.4 documentazione https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html.

Problemi correlati