문제

내 사이트에서 Lucene.user를 사용하여 웹 기반 구직 응용 프로그램에서 작업 중입니다. "Boston, MA"또는 기타 위치에서 100 마일 이내에있는 작업을 검색 할 수 있습니다. 또한 "REPING"(예 : Lucene이 반환 한 점수)별로 내림차순으로 정렬 된 검색 결과를 보여 주어야합니다.

나는 타사 API를 사용하여 도시의 반경 주어진 모든 도시를 가져오고 있습니다.이 API는 "Boston, MA"반경 100 마일 이내에 864 개 도시를 반환합니다.

"BuildNearestCitiesQuery"메소드의 일부인 다음 논리를 사용하여 City/State Lucene 쿼리를 구축하고 있습니다. 여기에서 가장 가까운 도시는 위의 API에 의해 반환 된 해시 가능입니다. 시티 이름 엉덩이 키와 Statecode를 가진 864 개 도시가 포함되어 있습니다. 그리고 FinalQuery는 Lucene BooleanQuery 객체로, 기술, 키워드 등과 같은 사용자가 입력 한 다른 검색 기준이 포함되어 있습니다.

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

그런 다음 FinalQuery 객체를 Lucene의 검색 방법에 입력하여 반경 100 마일 이내의 모든 작업을 얻습니다. :

searcher.Search(finalQuery, collector);

나는이 buildnearestcities Querery 메소드를 평균적으로 실행하는 데 무려 29 초가 걸린다는 것을 알았습니다. 진술.

주어진 위치에 대한 작업은 도시가 오늘 2 개의 작업 (특정 검색 기준을 충족) 할 수 있지만 3 일 후에 동일한 검색 기준에 대해서는 제로 작업을 가질 수 있다는 점에서 역동적 인 속성입니다. 따라서 "캐싱"을 사용할 수 없습니다. 여기.

이 논리를 최적화 할 수있는 방법이 있습니까?

참고로, 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));

독서 감사합니다! 나는 이것에 대한 당신의 도움에 정말 감사합니다.

자니

도움이 되었습니까?

해결책

코드를 완전히 이해하는지 확실하지 않지만 지리 공간 검색과 관련하여 필터 접근 방식이 더 적절할 수 있습니다. 어쩌면이 링크는 몇 가지 아이디어를 줄 수 있습니다. http://sujitpal.blogspot.com/2008/02/spatial-search-with-lucene.html

아마 당신은 사용할 수 있습니다 필터쿼리의 다른 부분에도 s. 솔직히 말해서 쿼리는 매우 복잡해 보입니다.

--튼튼한

다른 팁

와는 별개로 tempFinalQuery 주를 얻기 위해 사용하지 않고 불필요한지도 조회이기 때문에 게시 한 코드에는 너무 심각하지 않은 것 같습니다. 서식 외에 ...

항상 시간이 걸리면 Parse 방법, 여기에 코드를 게시하는 것이 합리적입니다.

나는 당신의 질문의 요점을 놓쳤을 수도 있지만 우편 번호에 대한 위도와 경도를 저장할 가능성이 있습니까? 이것이 옵션 인 경우 훨씬 더 간단한 스코어링 메트릭을 제공하는 두 좌표 사이의 거리를 계산할 수 있습니다.

가장 좋은 방법은 가장 가까운 도시 결정을 검색 필터로 옮기는 것입니다. 또한 필드 설정을 어떻게 재고 할 것입니다. 쿼리를 단순화 할 수 있도록 City+State가있는 한 용어를 작성하십시오.

제안 할 것입니다 :

  • 위치의 위도와 경도를 보관
  • 사용자가 도시와 거리에 들어가면 그것을 위도/론 가치와 학위로 바꿉니다.
  • 숫자 거리 LAT/LON 비교를 기반으로 단일의 간단한 조회를 수행하십시오.

이것이 어떻게 작동하는지에 대한 예를 볼 수 있습니다. 지오 :: 거리 Perl 모듈. 살펴보십시오 closest 방법의 메소드 원천, 이것은 간단한 SQL을 통해이 조회를 구현합니다.

여기 다른 사람들과 동의합니다. 또한 도시 이름에 대한 텍스트 검색을하는 것이 항상 그렇게 신뢰할 수있는 것은 아닙니다. 장소 이름 (특히 도시 내의 지역 영역) 사이에는 종종 약간의 주관성이 있습니다.

GEO 공간 쿼리를하는 것은 갈 길입니다. 나머지 설정을 모르면 조언하기가 어렵습니다. 예를 들어 Nhibernate 및 SQL Server 2008에 유창하게 내장 된 공간 지원이 있습니다. 그런 다음 검색을 수행 할 수 있습니다 매우 빠르고 효율적으로. 그러나 당신의 도전은 루센 내 에서이 일을하는 것입니다.

SQL Server에서 공간 지원을 사용하여 "첫 번째 패스"쿼리를 수행 한 다음 Lucene을 통해 결과를 실행할 수 있습니까?

공간 쿼리를 수행 할 때의 또 다른 주요 이점은 고객에게 승리하는 거리별로 쉽게 결과를 분류 할 수 있다는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top