Adding second facet to BrowseTest() unit test

Jun 21, 2012 at 5:43 AM

I've been playing with the unit test code in this project and wondering how the BrowseTest() method might be extended to demonstrate pulling more than one facet back? When I try, the facetMap always has still one entry in it (for "File Name").

I've tried something like this to add a facet for "Group" which I found by using Luke on the index:

 [Test]
        public void BrowseTest()
        {
            FacetHandler facetHandler = new MultiValueFacetHandler(fieldName);

            ICollection<FacetHandler> handlerList = new FacetHandler[] { facetHandler };

            // opening a lucene index

            string indexDir = Utils.GetTestData("Index");

            Directory idx = FSDirectory.Open(new System.IO.DirectoryInfo(indexDir));
            IndexReader reader = IndexReader.Open(idx, true);

            // decorate it with a bobo index reader
            BoboIndexReader boboReader = BoboIndexReader.GetInstance(reader, handlerList);

            // creating a browse request
            BrowseRequest browseRequest = new BrowseRequest();
            browseRequest.Count = 10;
            browseRequest.Offset = 0;
            browseRequest.Sort = new SortField[] { new SortField("LeafName") };
            browseRequest.FetchStoredFields = true;

            // add a selection
            BrowseSelection sel = new BrowseSelection(fieldName);
            //sel.addValue("21");
            browseRequest.AddSelection(sel);

            BrowseSelection sel2 = new BrowseSelection("Group");
            browseRequest.AddSelection(sel2);

            // parse a query
            QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "Entity", new KeywordAnalyzer());
            Query q = parser.Parse("SPListItem");
            browseRequest.Query = q;

            // add the facet output specs
            FacetSpec colorSpec = new FacetSpec();
            colorSpec.OrderBy = FacetSpec.FacetSortSpec.OrderHitsDesc;

            FacetSpec categorySpec = new FacetSpec();
            categorySpec.MinHitCount = 2;
            categorySpec.OrderBy = FacetSpec.FacetSortSpec.OrderHitsDesc;

            browseRequest.SetFacetSpec(fieldName, colorSpec);

            FacetSpec groupSpec = new FacetSpec();
            groupSpec.OrderBy = FacetSpec.FacetSortSpec.OrderHitsDesc;

            browseRequest.SetFacetSpec("Group", groupSpec);

            // 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 colorFacets = facetMap[fieldName];

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

            Debug.WriteLine("Facets:");

            foreach (BrowseFacet facet in facetVals)
            {
                Debug.WriteLine(facet.ToString());
            }

	    // produces KeyNotFoundException

            IFacetAccessible groupFacet = facetMap["Group"];

            var groupFacetValues = groupFacet.GetFacets();

            foreach (BrowseFacet facet in groupFacetValues)
            {
                Debug.WriteLine(facet.ToString());
            }

            Debug.WriteLine("Actual items:");

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

	    // grab the second 'page' of results...

            browseRequest.Offset = 11;

            result = browser.Browse(browseRequest);

            totalHits = result.NumHits;
             hits = result.Hits;

            facetMap = result.FacetMap;

            colorFacets = facetMap[fieldName];

            facetVals = colorFacets.GetFacets();

            Debug.WriteLine("Facets:");

            foreach (BrowseFacet facet in facetVals)
            {
                Debug.WriteLine(facet.ToString());
            }

            Debug.WriteLine("Actual items:");

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

 

Thanks!

Coordinator
Jun 21, 2012 at 10:04 AM
Edited Jun 21, 2012 at 10:05 AM

Hello. What you need is to extend facet handler collection with additional fields you need.

Something like this:

FacetHandler facetHandler1 = new MultiValueFacetHandler("File Type");
FacetHandler facetHandler2 = new MultiValueFacetHandler("Group");

ICollection handlerList = new FacetHandler[] { facetHandler1, facetHandler2 };
Jun 21, 2012 at 5:41 PM

Cool this works great.  Quick question about handler types. I read the documentation on the main BoboBrowse website ("Creating a Browse Index") and don't know if there is a better place to read a description of the different handlers in Bobo. I was wondering about SimpleFacetHandler vs. MultiValueFacetHandler and how to know if a field has been defined/indexed as something that can take multiple values. I don't know how to tell that in Luke or not.

When I use the changes you suggest (MultiValueFacetHandlers for both File Type and Group) this is what I get:

 

Facets:
dwp(60)
thmx(40)
webpart(26)
aspx(11)
master(7)
xsn(6)
png(4)
rules(3)
vdw(3)
xml(3)
xoml(3)
xlsx(2)
gif(1)
pdf(1)
content(22)
rollup(18)
search(17)
information(10)
my(10)
filters(9)
business(8)
data(8)
people(7)
navigation(6)
applications(5)
client(5)
office(5)
media(4)
documents(1)
Actual items:
default.master
v4.master
minimal.master
mysite.master
1_.000
3_.000
1073741823_.000
owatasks.dwp
owacalendar.dwp
Microsoft.Office.InfoPath.Server.BrowserForm.webpart

 

You can see the Group facets printed right after the File Type facet values (Content through documents). When I use both SimpleFacetHandlers the File Type facets listing does not change, but the Group facets does:

rollup(18)
search(17)
my(10)
filters(9)
data(8)
people(7)
navigation(6)
office(5)
media(4)
documents(1)

Notice the differences - facet values 'content', 'information', 'business','applications', 'client' are missing.

I'm guessing that the Group field in the index is multi-value (although I don't know how to check that in Luke), so I'm guessing its a matter of knowing exactly how your fields are set up, right?

Coordinator
Jun 21, 2012 at 6:09 PM

The main Bobo site is good. Since we don't have any documentation for .Net version, it could be the only source for valuable insights. 

The difference is how many tokens are stored for every field per document. Usually, for tokenized fields you will end up with many tokens in field.  That is the case for Group, which had been indexed as tokenizable (you can see that in the Luke).

But for faceted navigation you don't wanna use tokenized fields usually. Exception is only the field created for auto suggest/type a head feature. Instead you would add either one (or none) untokenized field value for every document (this is the case for SimpleFacetHandler) or more than one field value (then use MultiValueFacetHandler). 

Hope that helps.