You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@lucene.apache.org by Sanket Paranjape <sa...@gmail.com> on 2013/08/01 18:46:35 UTC

Lucene 4 - Faceted Search with Sorting

I am trying to move from lucene 2.4 to 4.4. I had used bobo-browse for
faceting in 2.4.

I used below code (from Lucene examples) to query documents and get facets.

    List<FacetRequest> categories = new ArrayList<FacetRequest>();
    categories.add(new CountFacetRequest(new CategoryPath("CATEGORY_PATH",
'/'), 10));
    FacetSearchParams searchParams = new FacetSearchParams(categories);
    TopScoreDocCollector topScoreDocCollector =
TopScoreDocCollector.create(200, true);
    FacetsCollector facetsCollector = FacetsCollector.create(searchParams,
indexReader, taxonomyReader);
    indexSearcher.search(new MatchAllDocsQuery(),
MultiCollector.wrap(topScoreDocCollector, facetsCollector));

Above code gives me results along with facets.

Now I want to add a Sort field on document, say I want to sort by name. I
can achieve this using following

    Sort sort = new Sort(new SortField("NAME", Type.STRING));
    TopFieldDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 100,
sort);

Now, how do I achieve sorting along with faceting, because there is no
method in IndexSearcher which has Collector and Sort.


I have asked this question on stackoverflow as well. (
http://stackoverflow.com/questions/17992183/lucene-4-faceted-search-with-sorting
)


Please Help !!

Re: Lucene 4 - Faceted Search with Sorting

Posted by Shai Erera <se...@gmail.com>.
Hi

Basically, every IndexSearch.search() variant has a matching Collector.
They are there for easier usage by users.
TopFieldCollector.create() takes searchAfter (TopFieldDoc), so you can use
it in conjunction with FacetsCollector as I've outlined before.

In general you're right that for pagination you don't need to collect
facets again. I would cache the List<FacetResult> though, and not the
FacetsCollector.
Maybe even cache the way it's output, e.g. the String that you send back.
But, note that such caching means the server becomes stateful, which
usually complicates matters for apps.
Whether it's a problem or not for your app, you'll be the judge, I just
wanted to point that out.

Shai


On Fri, Aug 2, 2013 at 9:35 AM, Sanket Paranjape <
sanket.paranjape.mailinglist@gmail.com> wrote:

> Hi Shai,
>
> Thanks for helping out.
>
> It worked. :)
>
> I also want to add pagination feature. This can be done via searchAfter
> method in IndexSearcher. But, this does not have Collector (I want facets
> from this).
>
> I think this has been done intentionally because facets would remain same
> while paginating/sorting.
>
> So my approach to this would be following.
>
> 1. On first search call below code to get first set of results along
>    with facets.
> 2. Save *last* ScoreDoc somewhere in the session so that it can be used
>    to pagination. Also save facetCollector so as to use it later on
>    pagination request to show facets.
> 3. On subsequent pagination requests use IndexSearcher.searchAfter
>    method to get next set of results using ScoreDoc from session.
> 4. If user want to narrow down on facets then follow steps from 1 to 3
>    using Drill-down feature.
>
> Am I correct?
>
> On 01-08-2013 11:33 PM, Shai Erera wrote:
>
>> Hi
>>
>> You should do the following:
>>
>> TopFieldCollector tfc = TopFieldCollector.create();
>> FacetsCollector fc = FacetsCollector.create();
>> searcher.search(query, MultiCollector.wrap(tfc, fc));
>>
>> Basically IndexSearcher.search(..., Sort) creates TopFieldCollector
>> internally, so you need to create it outside and wrap both collectors with
>> MultiCollector.
>>
>> BTW, you don't need to do new CategoryPath("CATEGORY_PATH", '/'), when the
>> category does not contain the delimiter.
>> You can use the vararg constructor which takes the path components
>> directly, if you have them already.
>>
>> Shai
>>
>>
>> On Thu, Aug 1, 2013 at 7:46 PM, Sanket Paranjape <
>> sanket.paranjape.mailinglist@**gmail.com<sa...@gmail.com>>
>> wrote:
>>
>>  I am trying to move from lucene 2.4 to 4.4. I had used bobo-browse for
>>> faceting in 2.4.
>>>
>>> I used below code (from Lucene examples) to query documents and get
>>> facets.
>>>
>>>      List<FacetRequest> categories = new ArrayList<FacetRequest>();
>>>      categories.add(new CountFacetRequest(new
>>> CategoryPath("CATEGORY_PATH",
>>> '/'), 10));
>>>      FacetSearchParams searchParams = new FacetSearchParams(categories);
>>>      TopScoreDocCollector topScoreDocCollector =
>>> TopScoreDocCollector.create(**200, true);
>>>      FacetsCollector facetsCollector = FacetsCollector.create(**
>>> searchParams,
>>> indexReader, taxonomyReader);
>>>      indexSearcher.search(new MatchAllDocsQuery(),
>>> MultiCollector.wrap(**topScoreDocCollector, facetsCollector));
>>>
>>> Above code gives me results along with facets.
>>>
>>> Now I want to add a Sort field on document, say I want to sort by name. I
>>> can achieve this using following
>>>
>>>      Sort sort = new Sort(new SortField("NAME", Type.STRING));
>>>      TopFieldDocs docs = indexSearcher.search(new MatchAllDocsQuery(),
>>> 100,
>>> sort);
>>>
>>> Now, how do I achieve sorting along with faceting, because there is no
>>> method in IndexSearcher which has Collector and Sort.
>>>
>>>
>>> I have asked this question on stackoverflow as well. (
>>>
>>> http://stackoverflow.com/**questions/17992183/lucene-4-**
>>> faceted-search-with-sorting<http://stackoverflow.com/questions/17992183/lucene-4-faceted-search-with-sorting>
>>> )
>>>
>>>
>>> Please Help !!
>>>
>>>
>

Re: Lucene 4 - Faceted Search with Sorting

Posted by Sanket Paranjape <sa...@gmail.com>.
Hi Shai,

Thanks for helping out.

It worked. :)

I also want to add pagination feature. This can be done via searchAfter 
method in IndexSearcher. But, this does not have Collector (I want 
facets from this).

I think this has been done intentionally because facets would remain 
same while paginating/sorting.

So my approach to this would be following.

 1. On first search call below code to get first set of results along
    with facets.
 2. Save *last* ScoreDoc somewhere in the session so that it can be used
    to pagination. Also save facetCollector so as to use it later on
    pagination request to show facets.
 3. On subsequent pagination requests use IndexSearcher.searchAfter
    method to get next set of results using ScoreDoc from session.
 4. If user want to narrow down on facets then follow steps from 1 to 3
    using Drill-down feature.

Am I correct?

On 01-08-2013 11:33 PM, Shai Erera wrote:
> Hi
>
> You should do the following:
>
> TopFieldCollector tfc = TopFieldCollector.create();
> FacetsCollector fc = FacetsCollector.create();
> searcher.search(query, MultiCollector.wrap(tfc, fc));
>
> Basically IndexSearcher.search(..., Sort) creates TopFieldCollector
> internally, so you need to create it outside and wrap both collectors with
> MultiCollector.
>
> BTW, you don't need to do new CategoryPath("CATEGORY_PATH", '/'), when the
> category does not contain the delimiter.
> You can use the vararg constructor which takes the path components
> directly, if you have them already.
>
> Shai
>
>
> On Thu, Aug 1, 2013 at 7:46 PM, Sanket Paranjape <
> sanket.paranjape.mailinglist@gmail.com> wrote:
>
>> I am trying to move from lucene 2.4 to 4.4. I had used bobo-browse for
>> faceting in 2.4.
>>
>> I used below code (from Lucene examples) to query documents and get facets.
>>
>>      List<FacetRequest> categories = new ArrayList<FacetRequest>();
>>      categories.add(new CountFacetRequest(new CategoryPath("CATEGORY_PATH",
>> '/'), 10));
>>      FacetSearchParams searchParams = new FacetSearchParams(categories);
>>      TopScoreDocCollector topScoreDocCollector =
>> TopScoreDocCollector.create(200, true);
>>      FacetsCollector facetsCollector = FacetsCollector.create(searchParams,
>> indexReader, taxonomyReader);
>>      indexSearcher.search(new MatchAllDocsQuery(),
>> MultiCollector.wrap(topScoreDocCollector, facetsCollector));
>>
>> Above code gives me results along with facets.
>>
>> Now I want to add a Sort field on document, say I want to sort by name. I
>> can achieve this using following
>>
>>      Sort sort = new Sort(new SortField("NAME", Type.STRING));
>>      TopFieldDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 100,
>> sort);
>>
>> Now, how do I achieve sorting along with faceting, because there is no
>> method in IndexSearcher which has Collector and Sort.
>>
>>
>> I have asked this question on stackoverflow as well. (
>>
>> http://stackoverflow.com/questions/17992183/lucene-4-faceted-search-with-sorting
>> )
>>
>>
>> Please Help !!
>>


Re: Lucene 4 - Faceted Search with Sorting

Posted by Shai Erera <se...@gmail.com>.
Hi

You should do the following:

TopFieldCollector tfc = TopFieldCollector.create();
FacetsCollector fc = FacetsCollector.create();
searcher.search(query, MultiCollector.wrap(tfc, fc));

Basically IndexSearcher.search(..., Sort) creates TopFieldCollector
internally, so you need to create it outside and wrap both collectors with
MultiCollector.

BTW, you don't need to do new CategoryPath("CATEGORY_PATH", '/'), when the
category does not contain the delimiter.
You can use the vararg constructor which takes the path components
directly, if you have them already.

Shai


On Thu, Aug 1, 2013 at 7:46 PM, Sanket Paranjape <
sanket.paranjape.mailinglist@gmail.com> wrote:

> I am trying to move from lucene 2.4 to 4.4. I had used bobo-browse for
> faceting in 2.4.
>
> I used below code (from Lucene examples) to query documents and get facets.
>
>     List<FacetRequest> categories = new ArrayList<FacetRequest>();
>     categories.add(new CountFacetRequest(new CategoryPath("CATEGORY_PATH",
> '/'), 10));
>     FacetSearchParams searchParams = new FacetSearchParams(categories);
>     TopScoreDocCollector topScoreDocCollector =
> TopScoreDocCollector.create(200, true);
>     FacetsCollector facetsCollector = FacetsCollector.create(searchParams,
> indexReader, taxonomyReader);
>     indexSearcher.search(new MatchAllDocsQuery(),
> MultiCollector.wrap(topScoreDocCollector, facetsCollector));
>
> Above code gives me results along with facets.
>
> Now I want to add a Sort field on document, say I want to sort by name. I
> can achieve this using following
>
>     Sort sort = new Sort(new SortField("NAME", Type.STRING));
>     TopFieldDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 100,
> sort);
>
> Now, how do I achieve sorting along with faceting, because there is no
> method in IndexSearcher which has Collector and Sort.
>
>
> I have asked this question on stackoverflow as well. (
>
> http://stackoverflow.com/questions/17992183/lucene-4-faceted-search-with-sorting
> )
>
>
> Please Help !!
>