Domanda

Sto lavorando su un'applicazione di ricerca di lavoro basata sul web utilizzando Lucene. L'utente sul mio sito può cercare lavori che si trovano entro un raggio di 100 miglia da "Boston, MA" o qualsiasi altra posizione. Inoltre, devo mostrare i risultati della ricerca ordinati per "pertinenza" (ad es. Punteggio restituito da lucene) in ordine decrescente.

Sto utilizzando un'API di terze parti per recuperare tutte le città nel raggio di una determinata città. Questa API mi restituisce circa 864 città entro un raggio di 100 miglia da "Boston, MA".

Sto costruendo la query Lucene città / stato utilizzando la seguente logica che fa parte della mia "quotazione BuildNearestCitiesQuery" metodo. Qui latestCities è una tabella hash restituita dall'API di cui sopra. Contiene 864 città con chiave ass CityName e StateCode come valore. E finalQuery è un oggetto Lucene BooleanQuery che contiene altri criteri di ricerca inseriti dall'utente come: competenze, parole chiave, ecc.

foreach (string city in nearestCities.Keys)

{

    BooleanQuery tempFinalQuery = finalQuery;

    cityStateQuery = new BooleanQuery();    

    queryCity = queryParserCity.Parse(city);

    queryState = queryParserState.Parse(((string[])nearestCities[city])[1]);

    cityStateQuery.Add(queryCity, BooleanClause.Occur.MUST); //must is like an AND

    cityStateQuery.Add(queryState, BooleanClause.Occur.MUST);

} 


nearestCityQuery.Add(cityStateQuery, BooleanClause.Occur.SHOULD); //should is like an OR



finalQuery.Add(nearestCityQuery, BooleanClause.Occur.MUST);

Ho quindi inserito l'oggetto finalQuery nel metodo di ricerca di Lucene per ottenere tutti i lavori entro un raggio di 100 miglia .:

searcher.Search(finalQuery, collector);

Ho scoperto che questo metodo BuildNearestCitiesQuery richiede 29 secondi in media per l'esecuzione, il che ovviamente è inaccettabile da qualsiasi standard di un sito Web. Ho anche scoperto che le dichiarazioni che riguardano "Parse" impiegare molto tempo per essere eseguito rispetto ad altre dichiarazioni.

Un lavoro per una determinata località è un attributo dinamico nel senso che una città potrebbe avere 2 lavori (che soddisfano un determinato criterio di ricerca) oggi, ma zero lavoro per gli stessi criteri di ricerca dopo 3 giorni. Quindi, non posso usare alcun " cache " qui.

Esiste un modo per ottimizzare questa logica? O del resto il mio approccio / algoritmo per trovare tutti i lavori entro 100 miglia usando Lucene?

Cordiali saluti, ecco come appare la mia indicizzazione in Lucene:

doc.Add(new Field("jobId", job.JobID.ToString().Trim(), Field.Store.YES, Field.Index.UN_TOKENIZED));

doc.Add(new Field("title", job.JobTitle.Trim(), Field.Store.YES, Field.Index.TOKENIZED));

doc.Add(new Field("description", job.JobDescription.Trim(), Field.Store.NO, Field.Index.TOKENIZED));

doc.Add(new Field("city", job.City.Trim(), Field.Store.YES, Field.Index.TOKENIZED , Field.TermVector.YES));

doc.Add(new Field("state", job.StateCode.Trim(), Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.YES));

doc.Add(new Field("citystate", job.City.Trim() + ", " + job.StateCode.Trim(), Field.Store.YES, Field.Index.UN_TOKENIZED , Field.TermVector.YES));

doc.Add(new Field("datePosted", jobPostedDateTime, Field.Store.YES, Field.Index.UN_TOKENIZED));

doc.Add(new Field("company", job.HiringCoName.Trim(), Field.Store.YES, Field.Index.TOKENIZED));

doc.Add(new Field("jobType", job.JobTypeID.ToString(), Field.Store.NO, Field.Index.UN_TOKENIZED,Field.TermVector.YES));

doc.Add(new Field("sector", job.SectorID.ToString(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.YES));

doc.Add(new Field("showAllJobs", "yy", Field.Store.NO, Field.Index.UN_TOKENIZED));

Grazie mille per la lettura! Gradirei davvero il tuo aiuto su questo.

Janis

È stato utile?

Soluzione

Non sono sicuro di aver compreso completamente il tuo codice, ma quando si tratta di ricerca geospaziale un approccio di filtro potrebbe essere più appropriato. Forse questo link può darti alcune idee - http: // sujitpal .blogspot.com / 2008/02 / spazio-cerca-con-lucene.html

Forse puoi usare Filtro anche per altre parti della tua query. Ad essere onesti, la tua richiesta sembra piuttosto complessa.

- Hardy

Altri suggerimenti

A parte il tempFinalQuery inutilizzato e una ricerca cartografica non necessaria per ottenere lo stato, non sembra esserci nulla di troppo egregio nel codice che pubblichi. Oltre alla formattazione ...

Se tutto il tempo è impiegato nei metodi Parse , pubblicare il loro codice qui avrebbe senso.

Potrei aver perso il punto della tua domanda, ma hai la possibilità di memorizzare latitudine e longitudine per i codici postali? Se questa è un'opzione, puoi quindi calcolare la distanza tra due coordinate fornendo una metrica di punteggio molto più semplice.

Credo che l'approccio migliore sia spostare la determinazione della città più vicina in un filtro di ricerca. Vorrei anche riconsiderare come hai impostato il campo; considera la possibilità di creare un termine con città + stato in modo da semplificare la query.

Suggerirei:

  • memorizzazione della latitudine e della longitudine dei luoghi quando arrivano
  • quando un utente inserisce una città e una distanza, trasformalo in un valore lat / lon e gradi
  • effettua una singola, semplice ricerca basata su confronti numerici lat / lon di distanza

Puoi vedere un esempio di come funziona nel Geo :: Distance Modulo Perl. Dai un'occhiata al metodo più vicino nel source , che implementa questa ricerca tramite SQL semplice.

Concordo con gli altri qui che questo puzza troppo. Anche fare una ricerca testuale sui nomi delle città non è sempre così affidabile. C'è spesso un po 'di soggettività tra i nomi dei luoghi (in particolare le aree all'interno di una città che potrebbero essere di per sé grandi).

Fare una query spaziale geografica è la strada da percorrere. Non conoscendo il resto del tuo set up è difficile consigliarlo. Il supporto spaziale è integrato in Fluent to NHibernate e, ad esempio, in SQL Server 2008. Puoi quindi effettuare una ricerca molto in modo rapido ed efficiente. Tuttavia, la tua sfida è far funzionare tutto questo in Lucene.

Puoi eventualmente fare un "primo passaggio" interrogare utilizzando il supporto spaziale in SQL Server e quindi eseguire quei risultati tramite Lucene?

L'altro grande vantaggio derivante dall'esecuzione di query spaziali è che puoi quindi facilmente ordinare i risultati in base alla distanza, il che è una vittoria per i tuoi clienti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top