Question

Feb 15, 2012 at 11:37 AM
I've been looking the code and the test but i still don't undertands some things.
1 -  // creating a browse request
            BrowseRequest browseRequest = new BrowseRequest();
            browseRequest.Count = 10;
            browseRequest.Offset = 0;
            browseRequest.FetchStoredFields = true;
If I want to search in all my index, what value i should set on Count?
2 - With Lucene, in all my search i was doing this:
BooleanQuery bq = new BooleanQuery();
                Query qf = new TermQuery(new Lucene.Net.Index.Term("IDCity", "24"));
                bq.Add(qf, BooleanClause.Occur.MUST);
This is replaced with this, isn´t ?
// add a selection
            BrowseSelection sel = new BrowseSelection("IDCity");
            sel.addValue("24");
            browseRequest.AddSelection(sel);
3 - When i create my index, i need to considerer something additional when i'm adding documents? 
Maybe IDCity and CityName?
This is my current index:
Document.Add(new Field("IDDoc", reader.GetInt32(0).ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
            document.Add(new Field("IDOperation", reader.GetInt32(1).ToString(), Field.Store.YES, Field.Index.ANALYZED));
            document.Add(new Field("IDType", reader.GetInt32(2).ToString(), Field.Store.YES, Field.Index.ANALYZED));
            document.Add(new Field("IDState", reader.GetInt32(6).ToString(), Field.Store.YES, Field.Index.ANALYZED));
            document.Add(new Field("IDCity", reader[7].ToString() != string.Empty ? reader.GetInt32(7).ToString() : "-1", Field.Store.YES, Field.Index.ANALYZED));
Thanks a lot!
Coordinator
Feb 15, 2012 at 4:33 PM

Hi ,

1. BrowseRequest.Count property is used to specify how many documents you want to retrieve from you index at one time. Usually you want get 10, 25, 50 documents per page. However, in any case the search is performed through entire index. 

2. With BoboBrowse you have two options. First, you could put the combined query into BrowseRequest.Query property. In this case your additional queries (like new TermQuery(new Lucene.Net.Index.Term("IDCity", "24"))) affect relevancy of search results. 

Second way, you could put you main query into BrowseRequest.Query and put subsequent filtering expressions (faceted selections) as BrowseSelection's. In this case these additional selections will not affect relevancy (which is good). Also filtering by browse selection works faster. 

So yes, your code looks good so far.

Actually, you have a third option too, to put additional expressions as Filter query, but Filter query isn't designed for faceted navigation anyway.

3. In general, all you need is to have your faceted fields indexed. You don't even need to store them. Also, I would suggest to index int fields slightly different. Something like this

NumericField field = new NumericField(fieldName, 0x20, Field.Store.YES, true); 
document.Add(field.SetIntValue(value));

Let me know how it works for you after all. 


Feb 15, 2012 at 7:18 PM

Thanks a lot for your answer!

About BrowseRequest.Count you are write, I only need 10 records for page, so the pagination how it works? 

Coordinator
Feb 16, 2012 at 5:56 AM

Just use BrowseRequest.Offset to skip number of items (not pages) in conjunction with BrowseRequest.Count = 10 . 

You could get total number of hits for your query from BrowseResult.NumHits property. 

Feb 16, 2012 at 2:02 PM

Hi!

Now I've understand! Thanks a lot!
I implemented the same example with bobo but when i show my facets the data is bad.

This is my code:

 

                //Opening a lucene index
                Directory idx = FSDirectory.Open(new DirectoryInfo(PATH_INDEX));
                IndexReader reader = IndexReader.Open(idx, true);

                //Decorate it with a bobo index reader
                FacetHandler facetHandler = new MultiValueFacetHandler("IDCity");
                ICollection<FacetHandler> handlerList = new FacetHandler[] { facetHandler };
                BoboIndexReader boboReader = BoboIndexReader.GetInstance(reader, handlerList);

                //Creating a browse request
                BrowseRequest browseRequest = new BrowseRequest();
                browseRequest.Count = 10;
                browseRequest.Offset = 0;//Use this to skip number of items (not pages) in conjunction with BrowseRequest.Count = 10 .
                browseRequest.Sort = new SortField[] { new SortField("Precio") };
                browseRequest.FetchStoredFields = true;

                //Add filters to query
                BrowseSelection sel = new BrowseSelection("IDState");
                sel.IsStrict = true;
                sel.AddValue("24");
                browseRequest.AddSelection(sel);

                browseRequest.Query = new MatchAllDocsQuery();

                //Add the facet output specs
                FacetSpec spec = new FacetSpec();
                spec.MinHitCount = 1;
                spec.OrderBy = FacetSpec.FacetSortSpec.OrderHitsDesc;
                browseRequest.SetFacetSpec("IDCity", spec);

                //Perform browse
                IBrowsable browser = new BoboBrowser(boboReader);

                BrowseResult result = browser.Browse(browseRequest);

                //Showing results now
                int totalHits = result.NumHits;
                BrowseHit[] hits = result.Hits;

                Dictionary<String, IFacetAccessible> facetMap = result.FacetMap;

                IFacetAccessible ciudadesFacets = facetMap["IDCity"];

                IEnumerable<BrowseFacet> facetVals = ciudadesFacets.GetFacets();

                Console.WriteLine("Total:" + totalHits);
                Console.WriteLine("Facets:");

                int i = 0;
                foreach (BrowseFacet facet in facetVals)
                {   
                    Console.WriteLine("IDCity:" + facet.ToString() + " - Cantidad:" + facet.HitCount);
                    i++;
                }

                //Get document's
                //for (int i = 0; i < hits.Length; ++i)
                //{
                //    BrowseHit browseHit = hits[i];
                //    Console.WriteLine(browseHit.StoredFields.Get("LeafName"));
                //}

                Console.ReadLine();

                boboReader.Close();
                reader.Close();

"facet.HitCount" is wrong and the "facet.ToString()" shows me things like "9!!<>!", "k3%" and similar.

If i change your suggestion of using "NumericField" in the creation of the lucene index, i get invalids "IDCity"

I'm doing something wrong. ??

Thanks!

 

 

Coordinator
Feb 16, 2012 at 2:39 PM

Try to use the NumericField approach and change this line:

FacetHandler facetHandler = new MultiValueFacetHandler("IDCity");

to

FacetHandler facetHandler = new SimpleFacetHandler("IDCity", new PredefinedTermListFactory<int>());

Also, what do you mean by invalids IDCity ? You may need to covert it back using NumericUtils.PrefixCodedToInt method

Feb 16, 2012 at 6:10 PM

ok. I've found the problem. The first filter (IDState) is not working.

In my example i've an index with this fields: IDState, IDCity, Price, etc etc.

And I want to get the all the data with an specific IDState and and a facet with all the cities.

Example:

IDState IDCity
24 1
24 2
12 3

If I search for State 24, i'll expect 2 facets (1 and 2)

My code is the following:

FacetHandler facetHandler = new SimpleFacetHandler("IDCity", new PredefinedTermListFactory<int>());

ICollection<FacetHandler> handlerList = new FacetHandler[] { acetHandler };
BoboIndexReader boboReader = BoboIndexReader.GetInstance(reader, handlerList);

//Creating a browse request
BrowseRequest browseRequest = new BrowseRequest();
browseRequest.Count = 10;
browseRequest.Offset = 0;//Use this to skip number of items (not pages) in conjunction with BrowseRequest.Count = 10 .
browseRequest.Sort = new SortField[] { new SortField("Price") };
browseRequest.FetchStoredFields = true;

//Add filters to query
BrowseSelection sel = new BrowseSelection("IDState");
sel.IsStrict = true;
sel.AddValue("24");
browseRequest.AddSelection(sel);

browseRequest.Query = new MatchAllDocsQuery();

//Add the facet output specs
FacetSpec spec = new FacetSpec();
spec.MinHitCount = 1;
spec.OrderBy = FacetSpec.FacetSortSpec.OrderHitsDesc;
browseRequest.SetFacetSpec("IDCity", spec);

//Perform browse
IBrowsable browser = new BoboBrowser(boboReader);

BrowseResult result = browser.Browse(browseRequest);

//Showing results now
int totalHits = result.NumHits;
BrowseHit[] hits = result.Hits;

Dictionary<String, IFacetAccessible> facetMap = result.FacetMap;

IFacetAccessible ciudadesFacets = facetMap["IDCity"];

IEnumerable<BrowseFacet> facetVals = ciudadesFacets.GetFacets();

What I must change?

Thanks!
 

Coordinator
Feb 17, 2012 at 12:15 PM

Check the list of all facet values returned with no browse selection. And just grub one value from this list and try to use it for filter. 

Feb 17, 2012 at 12:46 PM

Now it works! I use Lucene methods...

I've changed this code

//Add filters to query
BrowseSelection sel = new BrowseSelection("IDState");
sel.IsStrict = true;
sel.AddValue("24");
browseRequest.AddSelection(sel);

browseRequest.Query = new MatchAllDocsQuery();

for this one:
 //Add filters to query                
BooleanQuery bq = new BooleanQuery();                
Query qf = new TermQuery(new Lucene.Net.Index.Term("IDState", "24"));                
bq.Add(qf, BooleanClause.Occur.MUST);
browseRequest.Query = bq;

Thanks for all your help!