-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: How to avoid two way relationship in building index?
PostPosted: Thu Oct 14, 2010 5:24 am 
Beginner
Beginner

Joined: Mon Oct 27, 2008 6:26 am
Posts: 36
Greeting,

I am using hibernate search. Can anyone help me sort out following query issue I have?

I have a Student object that has a teacher type property. I mapped them as one-one relationship.

Student.hbm.xml:

<many-to-one unique="true" name="user" class="Student" column="student_fk" lazy="false" cascade="none" not-found="ignore" update="true" insert="true" />

So I could query students based on their teacher properties.

------------

Now, I have a new requirement on teacher query. I need to query teachers based on their student name similar as following:

query.add(new TermQuery(new Term("students.name", "jack"), BooleanClause.Occur.MUST);

As result, I need to build a two-way relatinoship bw Teacher and Student. But I just only need student's name in query. SO I added a mini version of student object that only contains student name, and mapped it in Teacher.hbm.xml

<set name="students" table="student" cascade="none" lazy="false">
<key column="user_name_fk" not-null="true" />
<one-to-many class="StudentMiniProfile" />
</set>

public class Teacher
{
private Set<StudentMiniProfile> students;

..getters and setters
}

After that, I started to index teachers, and did query. Search result is what I expected. However building teacher index became a time-consuming job. Because a teacher could have thousands of students, that means a lots of extra data queries at background.

--- StudentA has TeacherA. TeacherA has thousands Students including StudentA.

The true nightmare is to build student index. Remember that we have one2one relationship for Student and Teacher, so each of student has a new property in Index, student.teacher.students! (any way to avoid this in index?). It is extremely slow to build student index now.

BTW, is it at all possible to initialize a collection of student name using a single custom sql query in Teacher entity mapping? I think, The reason why the query slow is, hibernate have to iterate students by lots of quires to create a Teacher instance. If it is possbile, it might help my situation.

For property students in Teacher, I hope it is a String type instead of Set<StudentMiniProfile>, and the value format is name1,name2,name3... . Is any way to do it by mapping in hibernate?


Thanks,
Ian.


Top
 Profile  
 
 Post subject: Re: How to avoid two way relationship in building index?
PostPosted: Fri Oct 15, 2010 5:16 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
I am a little confused. Your example is not quite clear. It would help to see the fully annotated Teacher and Student classes.
Personally I would map the Teacher <-> Student relationship as a proper OneToMany (teacher side) <-> ManyToOne (student side) relationship. Even with thousands of students per teacher Hibernate and Hibernate Search should perform well if all mappings are correct. When does mean extremely slow anyways to you?

--Hardy


Top
 Profile  
 
 Post subject: Re: How to avoid two way relationship in building index?
PostPosted: Fri Oct 15, 2010 5:42 am 
Beginner
Beginner

Joined: Mon Oct 27, 2008 6:26 am
Posts: 36
public class Teacher extends User
{
@IndexedEmbedded
private Set<StudentMiniProfile> students;
...
}


public class StudentMiniProfile{
@Field(name = "name", index = org.hibernate.search.annotations.Index.TOKENIZED, store = Store.YES)
private String name;
....
}


public class Student implements Cloneable, Serializable
{
@IndexedEmbedded
private Teacher teacher;
...
}

Teacher.hbm.xml

<set name="students" table="student" cascade="none" lazy="false">
<key column="user_name_fk" not-null="true" />
<one-to-many class="StudentMiniProfile" />
</set>

Student.hbm.xml

<many-to-one unique="true" name="teacher" class="Teacher" column="user_name_fk" lazy="false" cascade="none" not-found="ignore" update="true" insert="true" />


In teacher search, I only need to search by student's name. So I created a StudentMiniProfile object that maps to same student table. It has only one property name.

-- query.add(new TermQuery(new Term("students.name", "jack"), BooleanClause.Occur.MUST);

So the assocaitions now are:

(teacher) <- ManyToOne (student side)

OneToMany (teacher side) --> StudentMiniProfile

If I build index for Teacher, index building would be slower than before (without adding students property into Teacher object). It is understandable, hibernate needs to do much more extra quires to load StudentMiniProfiles for each of teacher.

I have about 100,000 student records. If I build index for students, index building would be much slower. I think hibernate search also include teacher.students into student index (also means extra database quires), but actualy I do not need it.

Is anyway can avoid it?


Top
 Profile  
 
 Post subject: Re: How to avoid two way relationship in building index?
PostPosted: Sun Oct 17, 2010 3:17 pm 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
So are you having performance problems or not? The way you write you seem to "optimize" even before trying the obvious way. Also by introducing StudentMiniProfile you are limiting your ability to extend your search queries once new requirements are coming in. Also the code becomes harder to understand.

Regarding the @IndexeEmbedded - you might be running into recursive indexing. Have a look at the depth of @In dexedEmbedded which limits the number od recursions.

--Hardy


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.