2016-02-29 89 views
1

我想用數據庫使用hibernate搜索來返回記錄。搜索字符串實際上是一個短語時遇到困難,否則事情看起來不錯。 我有幾個領域上,我做了搜索,我不知道運行哪個領域,我應該做的查詢,所以我做了一個BooleanJunction和使用的should DSL方法是這樣的:休眠搜索結果太多

final Query spatialLuceneQuery = queryBuilder.spatial().within(200, Unit.KM).ofLatitude(latitude) 
      .andLongitude(longitude).createQuery(); 
bool.must(spatialLuceneQuery); 

if (tag != null) { 
    if (isPhrase(tag.getTag())) { 
     final Query phraseTagsLuceneQuery = queryBuilder.phrase().withSlop(2).onField("tags").sentence(tag.getTag()).createQuery(); 
     final Query phraseNameLuceneQuery = queryBuilder.phrase().onField("name").sentence(tag.getTag()).createQuery(); 
     final Query phraseDescriptionLuceneQuery = queryBuilder.phrase().withSlop(3).onField("description").sentence(tag.getTag()).createQuery(); 
     final Query phraseActiveSkillsLuceneQuery = queryBuilder.phrase().withSlop(1).onField("activeSkills").sentence(tag.getTag()).createQuery(); 
     bool.should(phraseTagsLuceneQuery).should(phraseActiveSkillsLuceneQuery).should(phraseNameLuceneQuery).should(phraseDescriptionLuceneQuery); 
    } else { 
     final Query fuzzyLuceneQuery = queryBuilder.keyword().fuzzy().withEditDistanceUpTo(2).withPrefixLength(1).onFields("tags", "activeSkills","name","description").matching(tag.getTag()).createQuery(); 
     bool.must(fuzzyLuceneQuery); 
    } 
} 

isPhrase方法返回true返回表中的所有記錄。我如何限制結果到相關的結果?

映射是這樣的:

@Entity 
@Table(name = "USER_INDEXED_SEARCH") 
@Indexed 
@Spatial(spatialMode = SpatialMode.RANGE) 
@AnalyzerDef(name = "customAnalyzer", tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class) , filters = { 
    @TokenFilterDef(factory = LowerCaseFilterFactory.class), 
    @TokenFilterDef(factory = ASCIIFoldingFilterFactory.class), 
    @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = { 
      @Parameter(name = "language", value = "Romanian") }) }) 
public class UserIndexedSearch extends DefaultLoggable { 

private static final long serialVersionUID = -8021827814963060426L; 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@DocumentId 
@Column(name = "USER_INDEXED_SEARCH_ID") 
private Integer userIndexSearchId; 

@Latitude 
@Column(name = "LATITUDE") 
private Double lat; 

@Longitude 
@Column(name = "LONGITUDE") 
private Double lon; 

@Column(name = "USER_ID") 
private Integer userId; 

@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO) 
@Analyzer(definition = "customAnalyzer") 
@Column(name = "TAGS") 
private String tags; 

@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO) 
@Analyzer(definition = "customAnalyzer") 
@Column(name = "ACTIVE_AREAS") 
private String activeAreas; 

@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO) 
@Analyzer(definition = "customAnalyzer") 
@Column(name = "ACTIVE_SKILLS") 
private String activeSkills; 

@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO) 
@Analyzer(definition = "customAnalyzer") 
@Column(name = "NAME") 
private String name; 

@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO) 
@Analyzer(definition = "customAnalyzer") 
@Column(name = "DESCRIPTION") 
private String description; 

謝謝!

+0

你的實際數據是怎樣的?你能舉個例子嗎?您正在使用短語查詢,其中的短語是標記嗎?這聽起來有點奇怪。標籤字段包含什麼?如果它是單個標籤,我不明白爲什麼你會在這裏使用短語查詢。你能解釋爲什麼你使用這種查詢類型嗎? – Hardy

+0

我有和哈代一樣的問題。想要補充的是,你經常要做的是不要排除許多結果,而是要得到「前N個」最相關的結果。如果你避免明確的排序,最相關的將是最重要的。另請參閱文檔中的「預測」,讓它顯示每個結果的分數和解釋,這對了解評分系統很有用。 – Sanne

+0

是的,我正在使用基於距離的分揀機,我希望過濾掉低於分數的結果 –

回答

1

當您發現自己有時會困惑於在查詢中顯示的結果或結果在查詢中沒有顯示 .Hibernate搜索 可讓您訪問給定結果的Lucene Explanation對象(在給定查詢中)。這個 類對於Lucene用戶來說相當先進,但可以很好地理解對象的 評分。有兩種方法來訪問對象說明對於給定結果:

  • 使用fullTextQuery.explain(int)方法
  • 使用投影

實施例使用投影:

FullTextQuery ftQuery = s.createFullTextQuery(luceneQuery, Dvd.class) 
     .setProjection(FullTextQuery.DOCUMENT_ID, FullTextQuery.EXPLANATION, FullTextQuery.THIS); 
@SuppressWarnings("unchecked") List<Object[]> results = ftQuery.list(); 
for (Object[] result : results) { 
    Explanation e = (Explanation) result[1]; 
    display(e.toString()); 
}