2015-09-05 9 views
6

Sono solo alcuni giorni nuovi in ​​ElasticSearch e, come esercizio di apprendimento, ho implementato un rudimentale processo di raschiatura che aggrega i lavori da alcuni siti di annunci di lavoro e popola un indice con alcuni dati per me con cui giocare.Aggregazione nella query inner_hits filtrata in nidificato in ElasticSearch

Il mio indice contiene un documento per ciascun sito Web che elenca i lavori. Una proprietà di ciascuno di questi documenti è una matrice 'jobs', che contiene un oggetto per ogni lavoro esistente su quel sito. Sto considerando di indicizzare ogni lavoro come un proprio documento (specialmente dal momento che la documentazione di ElasticSearch dice che inner_hits è una funzionalità sperimentale) ma per ora sto cercando di capire se posso realizzare ciò che voglio fare usando inner_hits e le funzionalità nidificate di ElasticSearch .

Sono in grado di interrogare, filtrare e restituire solo processi corrispondenti. Tuttavia, non sono sicuro di come applicare gli stessi vincoli inner_hits a un'aggregazione.

Questo è il mio mappatura:

{ 
    "jobsitesIdx" : { 
    "mappings" : { 
     "sites" : { 
     "properties" : { 
      "createdAt" : { 
      "type" : "date", 
      "format" : "dateOptionalTime" 
      }, 
      "jobs" : { 
      "type" : "nested", 
      "properties" : { 
       "company" : { 
       "type" : "string" 
       }, 
       "engagement" : { 
       "type" : "string" 
       }, 
       "link" : { 
       "type" : "string", 
       "index" : "not_analyzed" 
       }, 
       "location" : { 
       "type" : "string", 
       "fields" : { 
        "raw" : { 
        "type" : "string", 
        "index" : "not_analyzed" 
        } 
       } 
       }, 
       "title" : { 
       "type" : "string" 
       } 
      } 
      }, 
      "jobscount" : { 
      "type" : "long" 
      }, 
      "sitename" : { 
      "type" : "string" 
      }, 
      "url" : { 
      "type" : "string" 
      } 
     } 
     } 
    } 
    } 
} 

Si tratta di una query e di aggregazione che sto provando (da Node.js):

client.search({ 
    "index": 'jobsitesIdx, 
    "type": 'sites', 
    "body": { 


    "aggs" : { 
      "jobs" : { 
       "nested" : { 
        "path" : "jobs" 
       }, 
       "aggs" : { 
        "location" : { "terms" : { "field" : "jobs.location.raw", "size": 25 } }, 
        "company" : { "terms" : { "field" : "jobs.company.raw", "size": 25 } } 
       } 
      } 
     }, 


    "query": { 
     "filtered": { 
      "query": {"match_all": {}}, 
      "filter": { 
      "nested": { 
       "inner_hits" : { "size": 1000 }, 
       "path": "jobs", 
       "query":{ 
       "filtered": { 
        "query": { "match_all": {}}, 
        "filter": { 
        "and": [ 
         {"term": {"jobs.location": "york"}}, 
         {"term": {"jobs.location": "new"}} 
        ] 
        } 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
}, function (error, response) { 
    response.hits.hits.forEach(function(jobsite) { 
    jobs = jobsite.inner_hits.jobs.hits.hits; 

    jobs.forEach(function(job) { 
     console.log(job); 
    }); 

}); 

    console.log(response.aggregations.jobs.location.buckets); 
}); 

Questo mi restituisce tutti inner_hits di posti di lavoro a New York, ma l'aggregato mi sta mostrando i conti per ogni posizione e azienda, non solo per quelli che corrispondono alle inner_hits.

Qualche suggerimento su come ottenere l'aggregato solo sui dati contenuti nelle inner_hits corrispondenti?

Modifica: Sto aggiornando questo per includere un'esportazione dei dati di mappatura e indice, come richiesto. Ho esportato questo utilizzando lo strumento elasticdump di TaskRabbit, trovato qui: https://github.com/taskrabbit/elasticsearch-dump

L'indice: http://pastebin.com/WaZwBwn4 La mappatura: http://pastebin.com/ZkGnYN94

I dati sopra riportati collegato differisce dal codice di esempio nella mia domanda iniziale in quanto l'indice si chiama jobsites6 nei dati invece di jobsitesIdx come indicato nella domanda. Inoltre, il tipo nei dati è "lavoro" mentre nel codice sopra è "siti".

Ho inserito la richiamata nel codice sopra per visualizzare i dati di risposta. Sto vedendo solo i posti di lavoro a New York dal ciclo foreach delle inner_hits, come previsto, ma sto vedendo questa aggregazione per la posizione:

[ { key: 'New York, NY', doc_count: 243 }, 
    { key: 'San Francisco, CA', doc_count: 92 }, 
    { key: 'Chicago, IL', doc_count: 43 }, 
    { key: 'Boston, MA', doc_count: 39 }, 
    { key: 'Berlin, Germany', doc_count: 22 }, 
    { key: 'Seattle, WA', doc_count: 22 }, 
    { key: 'Los Angeles, CA', doc_count: 20 }, 
    { key: 'Austin, TX', doc_count: 18 }, 
    { key: 'Anywhere', doc_count: 16 }, 
    { key: 'Cupertino, CA', doc_count: 15 }, 
    { key: 'Washington D.C.', doc_count: 14 }, 
    { key: 'United States', doc_count: 11 }, 
    { key: 'Atlanta, GA', doc_count: 10 }, 
    { key: 'London, UK', doc_count: 10 }, 
    { key: 'Ulm, Deutschland', doc_count: 10 }, 
    { key: 'Riverton, UT', doc_count: 9 }, 
    { key: 'San Diego, CA', doc_count: 9 }, 
    { key: 'Charlotte, NC', doc_count: 8 }, 
    { key: 'Irvine, CA', doc_count: 8 }, 
    { key: 'London', doc_count: 8 }, 
    { key: 'San Mateo, CA', doc_count: 8 }, 
    { key: 'Boulder, CO', doc_count: 7 }, 
    { key: 'Houston, TX', doc_count: 7 }, 
    { key: 'Palo Alto, CA', doc_count: 7 }, 
    { key: 'Sydney, Australia', doc_count: 7 } ] 

Dato che i miei inner_hits sono limitati a quelli di New York, posso vedere che l'aggregazione non è sulle mie inner_hits perché mi sta dando dei conteggi per tutte le località.

+0

Potrebbe fornire alcuni dati di esempio (forse in un senso o qualcosa del genere)? E i risultati che vi aspettate saranno restituiti? –

risposta

10

È possibile ottenere questo risultato aggiungendo lo stesso filtro nella propria aggregazione per includere solo i lavori di New York. Inoltre nella tua seconda aggregazione avevi company.raw ma nella tua mappatura il campo jobs.company non ha una parte denominata raw, quindi probabilmente dovrai aggiungerla se desideri aggregarla sul nome della società non analizzata.

{ 
    "_source": [ 
    "sitename" 
    ], 
    "query": { 
    "filtered": { 
     "filter": { 
     "nested": { 
      "inner_hits": { 
      "size": 1000 
      }, 
      "path": "jobs", 
      "query": { 
      "filtered": { 
       "filter": { 
       "terms": { 
        "jobs.location": [ 
        "new", 
        "york" 
        ] 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    }, 
    "aggs": { 
    "jobs": { 
     "nested": { 
     "path": "jobs" 
     }, 
     "aggs": { 
     "only_loc": { 
      "filter": {   <----- add this filter 
      "terms": { 
       "jobs.location": [ 
       "new", 
       "york" 
       ] 
      } 
      }, 
      "aggs": { 
      "location": { 
       "terms": { 
       "field": "jobs.location.raw", 
       "size": 25 
       } 
      }, 
      "company": { 
       "terms": { 
       "field": "jobs.company", 
       "size": 25 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 
+0

Ho confermato che funziona, grazie!A quanto ho capito, i documenti padre restituiti da "query" influenzano l'ambito dell'aggregazione; sarebbe bello se ES permettesse che lo stesso si applichi con inner_hits senza dover ripetere di nuovo i vincoli del filtro in aggs. D'altra parte, forse l'utilizzo della funzione inner_hits "sperimentale" richiede problemi. Inoltre, avevo una mia nota per aggiungere jobs.company.raw la volta successiva in cui ho ricreato l'indice, buona presa. – mmccaff

Problemi correlati