当前位置: 首页 > 知识库问答 >
问题:

Hibernate搜索不返回结果

卜凯旋
2023-03-14

我正在用Hibernate Search 4.5.1和Spring 4.0.5版本构建一个应用程序。我正在尝试索引以下类:

@Entity
@Indexed
@Analyzer(impl= org.apache.lucene.analysis.standard.StandardAnalyzer.class)
@Table(name="SONG")
@XmlRootElement(name="song")
public class Song  
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID", updatable = false, nullable = false)
    private Long id;

    @Field(store = Store.YES)
    @Column(name="NAME",  length=255)
    private String name;

    @Field(store = Store.YES)
    @Column(name="ALBUM",  length=255)
    private String album;

    @Field(store = Store.YES)
    @Column(name="ARTIST",  length=255)
    private String artist;

    @NotNull
    @Column(name="PATH",  length=255)
    private String path;

    @NotNull
    @Column(name="PATH_COVER",  length=255)
    private String cover;

    @NotNull
    @Column(name="LAST_VOTE")
    private Date date;

    @Field(store = Store.YES)
    @NotNull
    @Column(name="N_VOTES")
    private int nvotes;

    @NotNull
    @Column(name="ACTIVE", nullable=false, columnDefinition="TINYINT(1) default 0")
    private boolean active;

    @OneToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="IMAGE_ID",insertable=true,updatable=true,nullable=false,unique=false)
    private Image image;

    @IndexedEmbedded
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PLAYLIST_ID", nullable = false)
    private PlayList playList;

    @OneToMany(mappedBy = "song")
    private Set<UserVotes> userServices = new HashSet<UserVotes>();

我正在构建一个junit测试用例,看起来如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:jukebox-servlet-test.xml"})
@Transactional
public class SongDaoTest {

     @Autowired
     public I_PlaceDao placeDao;
     @Autowired
     public I_PlayListDao playListDao;
     @Autowired
     public I_SongDao songDao;

     @Before
     public void prepare() throws Exception 
     {
            Operation operation = sequenceOf(CommonOperations.DISABLE_CONTRAINTS, CommonOperations.DELETE_ALL,CommonOperations.INSERT_SONG_DATA, CommonOperations.ENABLE_CONTRAINTS);
            DbSetup dbSetup = new DbSetup(new DriverManagerDestination("jdbc:mysql://localhost:3306/jukebox", "root", "mpsbart"), operation);
            dbSetup.launch();
            FullTextSession fullTextSession = Search.getFullTextSession(placeDao.getSession());
            fullTextSession.createIndexer().startAndWait();
     }

    @Test
    @Rollback(false)
    public void searchTest()
    {
        PlayList playList = playListDao.read(1l);
        List<Song> songs = songDao.search(playList, "offspring", 1, 10);
        assertEquals(10, songs.size());
    }
@SuppressWarnings("unchecked")
    public List<Song> search(PlayList playlist, String searchTerm,int page,int limit) 
    {
        FullTextSession fullTextSession = Search.getFullTextSession(getSession());
        QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Song.class).get();
        BooleanQuery luceneQuery = new BooleanQuery();
        luceneQuery.add(queryBuilder.keyword().onFields("name","album","artist").matching("*"+searchTerm+"*").createQuery(), BooleanClause.Occur.MUST); 
        luceneQuery.add(queryBuilder.phrase().onField("playList.place.id").sentence("\""+playlist.getPlace().getId()+"\"").createQuery(), BooleanClause.Occur.MUST);
        luceneQuery.add(queryBuilder.phrase().onField("playList.id").sentence("\""+playlist.getId()+"\"").createQuery(), BooleanClause.Occur.MUST);
        // wrap Lucene query in a javax.persistence.Query
        FullTextQuery query = fullTextSession.createFullTextQuery(luceneQuery, Song.class);
        org.apache.lucene.search.Sort sort = new Sort(new SortField("n_votes",SortField.INT));
        query.setSort(sort);
        List<Song> songs = query.setFirstResult(page*limit).setMaxResults(limit).list();
        return songs;
    }

我还注意到在luke lucene上,一些索引词的长度最多为6个字符,例如,一首歌的艺术家是“后代”,而索引中存储的词是“the”和“offspr”。第一个可以,但第二个不应该是“后代”。为什么要截断名字?

共有1个答案

詹杰
2023-03-14

如果它对任何人都有帮助,我可以通过将查询更改为以下内容来修复它:

        FullTextSession fullTextSession = org.hibernate.search.Search.getFullTextSession(getSession());  
    QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Song.class).get();  

    if(searchTerm==null || searchTerm.equals(""))
        searchTerm="*";
    else
        searchTerm="*"+searchTerm+"*";
    Query luceneQuery1 = qb.bool()
            .should(qb.keyword().wildcard().onField("name").matching(searchTerm).createQuery())
            .should(qb.keyword().wildcard().onField("album").matching(searchTerm).createQuery())
            .should(qb.keyword().wildcard().onField("artist").matching(searchTerm).createQuery()).createQuery();
    Query luceneQuery2 = qb.bool()
            .must(qb.keyword().wildcard().onField("playList.place.id").matching(playlist.getPlace().getId()).createQuery())
            .must(qb.keyword().wildcard().onField("playList.id").matching(playlist.getId()).createQuery())
            .createQuery();
    BooleanQuery finalLuceneQuery=new BooleanQuery();
    finalLuceneQuery.add(luceneQuery1, BooleanClause.Occur.MUST);
    finalLuceneQuery.add(luceneQuery2, BooleanClause.Occur.MUST);
    FullTextQuery query = fullTextSession.createFullTextQuery(finalLuceneQuery, Song.class);
    org.apache.lucene.search.Sort sort = new Sort(new SortField("nvotes",SortField.INT,true));
    query.setSort(sort);
    List<Song> songs = query.setFirstResult(page*limit).setMaxResults(limit).list();
 类似资料:
  • 当我使用MS Graph API并调用时,我会得到这个响应 {“@odata.context”:https://graph.microsoft.com/v1.0/$metadata#sites”,“value”:[]} 请求ID→cfb68a16-eb50-42ab-950c-fbfeec4Def5c 但是我可以使用有响应 {“@odata.context”:https://graph.micro

  • 问题内容: 我有一个运行中的elasticsearch的内存实例,并做了一些探索性的编码来学习搜索Java API。我能够将文档提交到索引并使用GET检索它们,但是当我尝试简单的搜索查询时,没有得到任何结果。 经过一些测试后,我认为问题出在我如何设置节点和关联的客户端(在内存中): 问题答案: Googleelasticsearch小组中的某个人很友好,可以在这里帮助我。将文档提交到内存节点后,我

  • 试图找出这个微不足道的例子的分数。我希望得到brenda eaton的文件,但我得到的是brenda fassie的最佳结果。

  • 创建新的。NET Framework 4.6.1控制台应用程序 为NEST 6.5.0和ElasticSearch.NET 6.5.0添加NuGet包 然后,我创建了一个新的弹性索引,其中包含具有“tags”属性的对象(类型为“mything”)。此标记是一组可能值中的随机逗号分隔的单词集。在测试中,我在索引中插入了100到5000项。我试了越来越少的可能的词在设置。

  • 我有三个索引,它们都共享一个特定的键值对。当我用api进行全面搜索时”http://localhost:9200/_search“使用请求正文 它只返回其中两个索引的结果。我尝试使用相同的请求正文,将url更改为仅在丢失的索引中搜索”http://localhost:9200/index_name/_search“这很管用。我有什么遗漏吗? 插入所有三个索引的代码遵循相同的过程,我使用elasti

  • 假设我有一个应用程序,有许多不同的实体,它们之间没有关系。 我想创建一个搜索,查询所有这些,但返回一个统一的类型,即: 你认为有办法让它起作用吗?