Frage

Am Arbeits auf Web-basierte Anwendung Jobsuche Lucene.User auf meiner Website mit nach Jobs suchen, die von sagen „Boston, MA“ oder jeden anderen Ort in einen Umkreis von 100 Meilen sind. Außerdem muss ich die Suchergebnisse nach „Relevanz“ sortiert anzuzeigen (dh. Von lucene zurück Score) in absteigender Reihenfolge.

Ich bin mit einem 3rd-Party-API innerhalb der gegebenen Radius eines city.This API gibt mir um 864 Orte im Umkreis von 100 Meilen Radius von „Boston, MA“ alle Städte zu holen.

Ich baue die Stadt / Staat Lucene Abfrage die folgende Logik verwendet, die ein Teil meiner „BuildNearestCitiesQuery“ Methode. Hier nearestCities ist eine Hash-Tabelle durch die obige API.It zurück enthält 864 Städte mit Cityname ass Schlüssel und state als Wert. Und finalQuery ist ein Lucene BooleanQuery Objekt, das vom Benutzer eingegebene Weitere Suchkriterien enthält wie: Fähigkeiten, Schlüsselwörter, usw.

.
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);

ich dann finalQuery Eingang Lucene der Suchmethode Objekt alle Aufträge innerhalb von 100 Meilen Radius zu erhalten.

searcher.Search(finalQuery, collector);

ich dieses BuildNearestCitiesQuery Methode dauert im Durchschnitt eine satte 29 Sekunden herausgefunden auszuführen, die offensichtlich von allen Standards eines website.I inakzeptabel ist auch herausgefunden, dass die Aussagen „Parse“ nehmen eine beträchtliche Menge an Zeit beteiligt wie auszuführen im Vergleich zu anderen Aussagen.

Ein Job für einen bestimmten Standort im Sinne ein dynamisches Attribut ist, dass eine Stadt 2 Arbeitsplätze haben könnte (Erfüllung einer bestimmten Suchkriterien) heute, aber Null Job für die gleichen Suchkriterien nach 3 days.So, ich kann nicht verwenden "Caching" hier.

Gibt es eine Möglichkeit, diese Logik zu optimieren? Oder, dass meinen ganzen Ansatz / Algorithmus Rolle auf alle Aufträge innerhalb von 100 Meilen mit Lucene zu finden?

FYI, hier ist, wie meine Indizierung in Lucene wie folgt aussieht:

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));

Dank einer Tonne für das Lesen! Ich würde schätzen Ihre Hilfe auf diesem wirklich.

Janis

War es hilfreich?

Lösung

Nicht ganz sicher, ob ich den Code vollständig verstehen, aber wenn es darum geht, ein Filteransatz Geospatial suchen könnte besser geeignet sein. Vielleicht kann diese Verbindung Ihnen ein paar Ideen - http: // sujitpal .blogspot.com / 2008/02 / Raum-Suche-mit-lucene.html

Vielleicht können Sie Filter s für andere Teile der Abfrage als auch. Um ehrlich zu sein Ihre Abfrage sehr komplex aussieht.

- Hardy

Andere Tipps

Neben tempFinalQuery ist ungenutzt und eine unnötige Karte Lookup, den Zustand zu erhalten, es scheint nicht zu etwas zu ungeheuerlich im Code zu sein, Sie schreiben. Neben der Formatierung ...

Wenn die ganze Zeit in den Parse Methoden genommen, ihren Code zu veröffentlichen hier Sinn machen würde.

Ich habe vielleicht den Punkt Ihrer Frage verpasst, aber haben Sie die Möglichkeit, für Postleitzahlen geografische Breite und Länge der Speicherung? Wenn das eine Option ist, könnten Sie dann den Abstand zwischen zwei Koordinaten berechnen eine viel einfachere Scoring-Metrik bereitstellt.

Ich glaube, dass der beste Ansatz ist es, die die nächste Stadt Bestimmung in einen Suchfilter zu bewegen. Ich würde auch überdenken, wie Sie das Feld Setup haben; betrachtet die Schaffung eine Bezeichnung, die Stadt + Staat hat, so dass die Abfrage vereinfachen würde.

Ich würde vorschlagen:

  • Speichern der Breite und Länge von Standorten, wie sie kommen in
  • wenn ein Benutzer eine Stadt und Abstand eindringen, schalten Sie, dass in ein lat / lon-Wert und Grad
  • tun, um eine einzige, einfache Lookup basierend auf numerischen Abstand lat / lon Vergleiche

Sie können ein Beispiel sehen, wie das funktioniert in der Geo :: Distance Perl-Modul. Werfen Sie einen Blick auf die closest Methode in der Quelle , die diese Lookup über einfache SQL implementiert.

Vereinbaren Sie mit den anderen hier, dass dies zu viel riecht. Auch auf Städtenamen eine textuelle Suche zu tun, ist nicht immer zuverlässig. Es ist oft ein bisschen Subjektivität zwischen Ortsnamen (insbesondere Bereiche innerhalb einer Stadt, die Macht an sich groß sein).

Doing a geo räumliche Abfrage ist der Weg zu gehen. Nicht zu wissen, den Rest Ihrer Einrichtung ist es schwer zu raten ist. Sie haben Räumliche Unterstützung in Fluent zu NHibernate gebaut und SQL Server 2008 zum Beispiel. Sie könnten dann eine Suche sehr schnell und effizient. Doch Ihre Herausforderung besteht darin, diese Arbeit in Lucene zu bekommen.

Sie könnten möglicherweise eine „first pass“ Abfrage mit räumlichen Unterstützung tun in SQL Server, und dann diese Ergebnisse durch Lucene laufen?

Der andere große Vorteil räumliche Abfragen zu tun, ist, dass Sie können dann Ihre Ergebnisse leicht nach Entfernung sortiert werden, die ein Gewinn für Ihre Kunden ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top