Main Overview Wiki Issues Forum Build Fisheye
Issue Details (XML | Word | Printable)

Key: CMP-278
Type: New Feature New Feature
Status: Open Open
Priority: Major Major
Assignee: Shay Banon
Reporter: Sami Dalouche
Votes: 0
Watchers: 2

If you were logged in you would be able to see more operations.

Sub Index hashing function : should provide more information

Created: 01/Oct/06 12:29 PM   Updated: 07/Feb/07 05:15 AM
Component/s: Compass::Core
Affects Version/s: None
Fix Version/s: None

 Description  « Hide

It would be really nice if the Custom Sub Index Hashing interface were giving a little more information.

Curently, the signature is :
mapSubIndex(String alias, Property[] ids)

It would be really nice if it was possible to get not only the id, but also the additional properties of the class, so that the function can be a little smarter.

Another room for improvement could be to have the Custom Sub Index hash object be instanciated by spring. Currently, in order for the function to be smart (e.g. access spring services), it is necessary to use AspectJ/Spring integration, to get the dependency magically injected...


 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Shay Banon added a comment - 02/Oct/06 12:18 PM
what other properties do you need? When I design an API, I try to make it as "small" as possible. This usually makes it more reselient when it comes to changes.

Also, as for injecting Spring implementation, naturally it is possible, I just never thought that it would be required on top of the ability to inject settings to it. What do you think?

Sami Dalouche added a comment - 02/Oct/06 05:07 PM
Ok, so to make it simple, here is a concrete Example.

I have 2 classes : Country and City, and I want to index the City Class, with a subindex for every Country.
(250 countries totally, so 250 sub indexes).

Country {
long id ;
String isoCode;

City{ @SearchableId @Id long id; @SearchableProperty(name="cityName") String name @ManyToOne Country country; }

So, in order to achieve what I want, here is the pseudo code :
mapSubIndex(String alias, Property[] ids){ 1. cityDao.findById(ids[0])); 2. Once I have the City, I can city.getCountry() 3. return country.getName(); }

Problems :
1. Since compass already fetched the instance of City, I find it a little sad to re-query the Dao (I know that there are caching solutions available, but ...) I'd just like the function to pass my entity, or to pass all properties of my entities. Or maybe all the properties that are annotated with some @PassToSubIndexFunction, something like that...

2. I need my Daos to be injected. This isn't really a problem since I am using Spring / AspectJ integration, but I'd still like to avoid using magical dependency injection to avoid making the system impossible to understand by another person..

3. I guess that step is unavoidable, but then it's more my problem than Compass'

Hope that I clearly explained my view. I mean, I may not use the system the way it was intented to work, so if you think this feature clearly doesn't match the sub index vision, you can drop it. However, this would be useful to me to have something like that In the meanwhile, I can always work with the current solution

Shay Banon added a comment - 03/Oct/06 05:38 PM
There is a reason why only the ids are passed to the sub index hashing. It is because the hashing is tightly coupled to the ids, which means that if you change the id, you need first to delete the previous entry with the mentioned id, and then add it again. Maybe it is not documented correctly in the documentation, and I should emphasise it. When Compass goes and updates a searchable object, it uses the ids to find the sub index to delete it from, and then add it again. If the ids changes, it will not delete the correct entry from the appropriate sub index (this is how Compass works even without the new sub index hashing).

If you want to perform the hashing based on the city, I would recommend having another id in Compass that has the city name. And if it changes, first delete the old one from compass, and then add the new one. I know that sadly it will probably require "Compass" aware code within your dao that updates a City, but there is no way around it that I can think of.

By the way, what is wrong with using the modulo implementation based on the ids of the City? 250 sub indexes sounds like a big number of sub indexes and might result in poor performance of search. What are you trying to achieve with the sub index hashing?

Sami Dalouche added a comment - 04/Oct/06 12:50 AM
Oh, ok, I had no idea (well, I actually didn't think of) about the relationship between update/delete and sub indexes.

Basically, what I want to achieve, is a fuzzy search on the city Names. The problem of that is that fuzzy searching is really really really slow, no matter what I do. (3-4 seconds for a 2 million city database). So, what I want to do is split the cities to different indexes (1 sub index per Country), and whenever I have to search for a city, I know what the country is, so that I can use sub indexes.

I guess I could add @SearchableId on the Country field of the city (actually, I didn't think of that either, since it was not a real Id).. I have not even thought of doing that, not sure whether it would work (since it is a ManyToOne relationship..).

Sami Dalouche added a comment - 06/Oct/06 11:46 AM
Thanks for the help, I am adopting the getCountryAsString solution, and using AspectJ / SPring 2 AOP allows me to get my DAO reference, then re-query the database, and so on...

However, I guess a JIRA issue isn't really the place to ask for help, so you can mark the feature request as "won't fix", or something similar, and if I have further questions on this topic, I'll post on the forums, which are more suitable for this task

(Just some additional proposition for this issue : Would it be aligned with your design vision if you added a @PassToSubIndexHash annotation, that we could use to annotate beans, and add a Property [] array to the SubIndexHash signature, that contains all the properties marked with this annotation ?

Sami Dalouche

Shay Banon added a comment - 06/Oct/06 12:08 PM
If you have the getCountryAsString, why would you need to dao for? You would get the country name as part of the parameters ids passed to the hashing, right? Or maybe I missed something.


Sure, in hindsight, the forum would have been a valid place for this thread. But I can understand why you raised it, that's ok.

Sami Dalouche added a comment - 06/Oct/06 01:03 PM
I think I've not been clear in my previous answer.

Actually, I don't need the DAO, except to implement the getSubIndexes() function, which needs to query the database for all the countries (unless I hard code them...)

Shay Banon added a comment - 06/Oct/06 01:17 PM
Ok, got you. I will close the issue soon.