/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.itest.search;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import com.enonic.cms.core.content.ContentKey;
import com.enonic.cms.core.content.category.CategoryKey;
import com.enonic.cms.core.content.contenttype.ContentTypeKey;
import com.enonic.cms.core.content.index.ContentIndexQuery;
import com.enonic.cms.core.content.index.UserDefinedField;
import com.enonic.cms.core.content.resultset.ContentResultSet;
import com.enonic.cms.core.search.facet.FacetQueryException;
import com.enonic.cms.core.search.query.ContentDocument;
import com.enonic.cms.core.search.query.SimpleText;
import com.enonic.cms.core.search.result.FacetResultSet;
import com.enonic.cms.core.search.result.FacetsResultSet;
import com.enonic.cms.core.search.result.TermsFacetResultSet;
import static org.junit.Assert.*;
public class ContentIndexServiceImpl_facetTermsFacetTest
extends ContentIndexServiceFacetTestBase
{
@Test
public void query_with_no_facet()
{
setUpValuesWithFacetGoodies();
ContentIndexQuery query = new ContentIndexQuery( "" );
final ContentResultSet result = contentIndexService.query( query );
final FacetsResultSet facetsResultSet = result.getFacetsResultSet();
assertTrue( facetsResultSet == null );
}
@Test
public void single_facet()
{
setUpValuesWithFacetGoodies();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
final String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type</indexes>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
final ContentResultSet result = contentIndexService.query( query );
final FacetsResultSet facetsResultSet = result.getFacetsResultSet();
assertNotNull( facetsResultSet );
assertTrue( facetsResultSet.iterator().hasNext() );
final FacetResultSet termFacet = facetsResultSet.iterator().next();
assertNotNull( termFacet );
assertEquals( facetName, termFacet.getName() );
assertTrue( termFacet instanceof TermsFacetResultSet );
TermsFacetResultSet termFacetResultSet = (TermsFacetResultSet) termFacet;
final Map<String, Integer> results = termFacetResultSet.getResults();
assertEquals( 2L, (long) results.get( "robot" ) );
assertEquals( 3L, (long) results.get( "human" ) );
assertEquals( 1L, (long) results.get( "alien" ) );
String expectedXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<content>\n" +
" <facets>\n" +
" <terms name=\"specietypes\" total=\"6\" missing=\"0\" other=\"0\">\n" +
" <term hits=\"3\">human</term>\n" +
" <term hits=\"2\">robot</term>\n" +
" <term hits=\"1\">alien</term>\n" +
" </terms>\n" +
" </facets>\n" +
"</content>";
createAndCompareResultAsXml( result, expectedXml );
}
@Test
public void multi_facets()
{
// Setup standard values
setUpValuesWithFacetGoodies();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetDefinition = "<facets>\n" +
" <terms name=\"facet1\">\n" +
" <indexes>data/person/type</indexes>\n" +
" </terms>\n" +
" <terms name=\"facet2\">\n" +
" <indexes>data/person/drink</indexes>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
final ContentResultSet result = contentIndexService.query( query );
FacetsResultSet facetsResultSet = result.getFacetsResultSet();
assertNotNull( facetsResultSet );
assertTrue( facetsResultSet.iterator().hasNext() );
FacetResultSet termFacet = facetsResultSet.iterator().next();
assertNotNull( termFacet );
assertTrue( termFacet instanceof TermsFacetResultSet );
termFacet = facetsResultSet.iterator().next();
assertNotNull( termFacet );
assertTrue( termFacet instanceof TermsFacetResultSet );
String expectedXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<content>\n" +
" <facets>\n" +
" <terms name=\"facet1\" total=\"6\" missing=\"0\" other=\"0\">\n" +
" <term hits=\"3\">human</term>\n" +
" <term hits=\"2\">robot</term>\n" +
" <term hits=\"1\">alien</term>\n" +
" </terms>\n" +
" <terms name=\"facet2\" total=\"6\" missing=\"0\" other=\"0\">\n" +
" <term hits=\"3\">beer</term>\n" +
" <term hits=\"2\">oil</term>\n" +
" <term hits=\"1\">blood</term>\n" +
" </terms>\n" +
" </facets>\n" +
"</content>";
createAndCompareResultAsXml( result, expectedXml );
}
@Test
public void size()
{
setUpValuesWithFacetGoodies();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
final String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type</indexes>\n" +
" <count>3</count>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
final ContentResultSet result = contentIndexService.query( query );
final FacetsResultSet facetsResultSet = result.getFacetsResultSet();
assertNotNull( facetsResultSet );
assertTrue( facetsResultSet.iterator().hasNext() );
final FacetResultSet termFacet = facetsResultSet.iterator().next();
assertNotNull( termFacet );
assertEquals( facetName, termFacet.getName() );
assertTrue( termFacet instanceof TermsFacetResultSet );
TermsFacetResultSet termFacetResultSet = (TermsFacetResultSet) termFacet;
final Map<String, Integer> results = termFacetResultSet.getResults();
assertEquals( 3, results.keySet().size() );
String expectedXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<content>\n" +
" <facets>\n" +
" <terms name=\"specietypes\" total=\"6\" missing=\"0\" other=\"0\">\n" +
" <term hits=\"3\">human</term>\n" +
" <term hits=\"2\">robot</term>\n" +
" <term hits=\"1\">alien</term>\n" +
" </terms>\n" +
" </facets>\n" +
"</content>\n";
createAndCompareResultAsXml( result, expectedXml );
}
@Test
public void fields()
{
setUpValuesWithFacetGoodies();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
final String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type,data/person/type,data/person/gender,data/person/drink</indexes>\n" +
" <count>3</count>\n" +
" <orderby>hits</orderby>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
final ContentResultSet result = contentIndexService.query( query );
final FacetsResultSet facetsResultSet = result.getFacetsResultSet();
assertNotNull( facetsResultSet );
assertTrue( facetsResultSet.iterator().hasNext() );
final FacetResultSet termFacet = facetsResultSet.iterator().next();
assertNotNull( termFacet );
assertEquals( facetName, termFacet.getName() );
assertTrue( termFacet instanceof TermsFacetResultSet );
TermsFacetResultSet termFacetResultSet = (TermsFacetResultSet) termFacet;
final Map<String, Integer> results = termFacetResultSet.getResults();
assertEquals( 4L, (long) results.get( "male" ) );
assertEquals( 3L, (long) results.get( "human" ) );
assertEquals( 3L, (long) results.get( "beer" ) );
String expectedXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<content>\n" +
" <facets>\n" +
" <terms name=\"specietypes\" total=\"18\" missing=\"0\" other=\"8\">\n" +
" <term hits=\"4\">male</term>\n" +
" <term hits=\"3\">human</term>\n" +
" <term hits=\"3\">beer</term>\n" +
" </terms>\n" +
" </facets>\n" +
"</content>";
createAndCompareResultAsXml( result, expectedXml );
}
@Test
public void ordering_default()
{
setUpValuesWithFacetGoodies();
flushIndex();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type</indexes>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
ContentResultSet result = contentIndexService.query( query );
TermsFacetResultSet termFacetResultSet = getTermFacetResultSet( result );
Iterator<String> resultIterator = getResultIterator( termFacetResultSet );
// Default sorting count
assertEquals( "human", resultIterator.next() );
assertEquals( "robot", resultIterator.next() );
assertEquals( "alien", resultIterator.next() );
String expectedXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<content>\n" +
" <facets>\n" +
" <terms name=\"specietypes\" total=\"6\" missing=\"0\" other=\"0\">\n" +
" <term hits=\"3\">human</term>\n" +
" <term hits=\"2\">robot</term>\n" +
" <term hits=\"1\">alien</term>\n" +
" </terms>\n" +
" </facets>\n" +
"</content>";
createAndCompareResultAsXml( result, expectedXml );
}
@Test
public void ordering_reverse_count()
{
setUpValuesWithFacetGoodies();
flushIndex();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type</indexes>\n" +
" <orderby>hits ASC</orderby>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
ContentResultSet result = contentIndexService.query( query );
TermsFacetResultSet termFacetResultSet = getTermFacetResultSet( result );
Iterator<String> resultIterator = getResultIterator( termFacetResultSet );
// Default sorting count
assertEquals( "alien", resultIterator.next() );
assertEquals( "robot", resultIterator.next() );
assertEquals( "human", resultIterator.next() );
String expectedXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<content>\n" +
" <facets>\n" +
" <terms name=\"specietypes\" total=\"6\" missing=\"0\" other=\"0\">\n" +
" <term hits=\"1\">alien</term>\n" +
" <term hits=\"2\">robot</term>\n" +
" <term hits=\"3\">human</term>\n" +
" </terms>\n" +
" </facets>\n" +
"</content>";
createAndCompareResultAsXml( result, expectedXml );
}
@Test
public void ordering_term()
{
setUpValuesWithFacetGoodies();
flushIndex();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type</indexes>\n" +
" <orderby>term</orderby>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
ContentResultSet result = contentIndexService.query( query );
TermsFacetResultSet termFacetResultSet = getTermFacetResultSet( result );
Iterator<String> resultIterator = getResultIterator( termFacetResultSet );
// Default sorting count
assertEquals( "alien", resultIterator.next() );
assertEquals( "human", resultIterator.next() );
assertEquals( "robot", resultIterator.next() );
String expectedXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<content>\n" +
" <facets>\n" +
" <terms name=\"specietypes\" total=\"6\" missing=\"0\" other=\"0\">\n" +
" <term hits=\"1\">alien</term>\n" +
" <term hits=\"3\">human</term>\n" +
" <term hits=\"2\">robot</term>\n" +
" </terms>\n" +
" </facets>\n" +
"</content>\n" +
"\n";
createAndCompareResultAsXml( result, expectedXml );
}
@Test
public void ordering_reverse_term()
{
setUpValuesWithFacetGoodies();
flushIndex();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type</indexes>\n" +
" <orderby>term ASC</orderby>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
ContentResultSet result = contentIndexService.query( query );
TermsFacetResultSet termFacetResultSet = getTermFacetResultSet( result );
Iterator<String> resultIterator = getResultIterator( termFacetResultSet );
// Default sorting count
assertEquals( "robot", resultIterator.next() );
assertEquals( "human", resultIterator.next() );
assertEquals( "alien", resultIterator.next() );
String expectedXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<content>\n" +
" <facets>\n" +
" <terms name=\"specietypes\" total=\"6\" missing=\"0\" other=\"0\">\n" +
" <term hits=\"2\">robot</term>\n" +
" <term hits=\"3\">human</term>\n" +
" <term hits=\"1\">alien</term>\n" +
" </terms>\n" +
" </facets>\n" +
"</content>\n";
createAndCompareResultAsXml( result, expectedXml );
}
@Test(expected = FacetQueryException.class)
public void invalid_order_parameter()
{
setUpValuesWithFacetGoodies();
flushIndex();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type</indexes>\n" +
" <orderby>sushi</orderby>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
contentIndexService.query( query );
}
@Test
public void exclude_single_field()
{
setUpValuesWithFacetGoodies();
flushIndex();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type</indexes>\n" +
" <exclude>robot</exclude>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
ContentResultSet result = contentIndexService.query( query );
TermsFacetResultSet termFacetResultSet = getTermFacetResultSet( result );
Iterator<String> resultIterator = getResultIterator( termFacetResultSet );
// Default sorting count
assertEquals( "human", resultIterator.next() );
assertEquals( "alien", resultIterator.next() );
assertFalse( resultIterator.hasNext() );
}
@Test
public void exclude_multiple_fields()
{
setUpValuesWithFacetGoodies();
flushIndex();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/type</indexes>\n" +
" <exclude>robot,alien</exclude>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
ContentResultSet result = contentIndexService.query( query );
TermsFacetResultSet termFacetResultSet = getTermFacetResultSet( result );
Iterator<String> resultIterator = getResultIterator( termFacetResultSet );
// Default sorting count
assertEquals( "human", resultIterator.next() );
assertFalse( resultIterator.hasNext() );
}
@Test
public void regexp()
{
setUpValuesWithFacetGoodies();
flushIndex();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
final String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/food</indexes>\n" +
" <regex>.*h.*</regex>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
final ContentResultSet result = contentIndexService.query( query );
final FacetsResultSet facetsResultSet = result.getFacetsResultSet();
assertNotNull( facetsResultSet );
assertTrue( facetsResultSet.iterator().hasNext() );
final FacetResultSet termFacet = facetsResultSet.iterator().next();
assertNotNull( termFacet );
assertEquals( facetName, termFacet.getName() );
assertTrue( termFacet instanceof TermsFacetResultSet );
TermsFacetResultSet termFacetResultSet = (TermsFacetResultSet) termFacet;
final Map<String, Integer> results = termFacetResultSet.getResults();
assertEquals( 1L, (long) results.get( "sushi" ) );
assertEquals( 1L, (long) results.get( "shells" ) );
}
@Test
public void regexp_with_flag()
{
setUpValuesWithFacetGoodies();
flushIndex();
ContentIndexQuery query = new ContentIndexQuery( "" );
final String facetName = "specietypes";
final String facetDefinition = "<facets>\n" +
" <terms name=\"" + facetName + "\">\n" +
" <indexes>data/person/food</indexes>\n" +
" <regex>S.*</regex>\n" +
" <regex-flags>CASE_INSENSITIVE,DOTALL</regex-flags>\n" +
" </terms>\n" +
"</facets>";
query.setFacets( facetDefinition );
final ContentResultSet result = contentIndexService.query( query );
final FacetsResultSet facetsResultSet = result.getFacetsResultSet();
assertNotNull( facetsResultSet );
assertTrue( facetsResultSet.iterator().hasNext() );
final FacetResultSet termFacet = facetsResultSet.iterator().next();
assertNotNull( termFacet );
assertEquals( facetName, termFacet.getName() );
assertTrue( termFacet instanceof TermsFacetResultSet );
TermsFacetResultSet termFacetResultSet = (TermsFacetResultSet) termFacet;
final Map<String, Integer> results = termFacetResultSet.getResults();
assertEquals( 1L, (long) results.get( "sushi" ) );
assertEquals( 1L, (long) results.get( "shells" ) );
}
private TermsFacetResultSet getTermFacetResultSet( final ContentResultSet result )
{
FacetsResultSet facetsResultSet = result.getFacetsResultSet();
FacetResultSet termFacet = facetsResultSet.iterator().next();
return (TermsFacetResultSet) termFacet;
}
private Iterator<String> getResultIterator( final TermsFacetResultSet termFacetResultSet )
{
Map<String, Integer> results = termFacetResultSet.getResults();
Set<String> strings = results.keySet();
return strings.iterator();
}
protected void setUpValuesWithFacetGoodies()
{
final GregorianCalendar date = new GregorianCalendar( 2008, Calendar.FEBRUARY, 28 );
ContentDocument doc1 = new ContentDocument( new ContentKey( 1 ) );
setMetadata( date, doc1 );
doc1.setTitle( "Homer" );
doc1.addUserDefinedField( "data/person/type", new SimpleText( "human" ) );
doc1.addUserDefinedField( "data/person/gender", "male" );
doc1.addUserDefinedField( "data/person/age", new SimpleText( "39" ) );
doc1.addUserDefinedField( "data/person/food", new SimpleText( "pizza" ) );
doc1.addUserDefinedField( "data/person/drink", "beer" );
contentIndexService.index( doc1 );
ContentDocument doc2 = new ContentDocument( new ContentKey( 2 ) );
setMetadata( date, doc2 );
doc2.setTitle( "r2d2" );
doc2.addUserDefinedField( "data/person/type", new SimpleText( "robot" ) );
doc2.addUserDefinedField( "data/person/gender", "unknown" );
doc2.addUserDefinedField( "data/person/age", new SimpleText( "449" ) );
doc2.addUserDefinedField( "data/person/food", new SimpleText( "oil" ) );
doc2.addUserDefinedField( "data/person/drink", "oil" );
contentIndexService.index( doc2 );
ContentDocument doc3 = new ContentDocument( new ContentKey( 3 ) );
setMetadata( date, doc3 );
doc3.setTitle( "c3p0" );
doc3.addUserDefinedField( "data/person/type", new SimpleText( "robot" ) );
doc3.addUserDefinedField( "data/person/gender", "male" );
doc3.addUserDefinedField( "data/person/age", new SimpleText( "150" ) );
doc3.addUserDefinedField( "data/person/food", new SimpleText( "oil" ) );
doc3.addUserDefinedField( "data/person/drink", "oil" );
contentIndexService.index( doc3 );
ContentDocument doc4 = new ContentDocument( new ContentKey( 4 ) );
setMetadata( date, doc4 );
doc4.setTitle( "Runar" );
doc4.addUserDefinedField( "data/person/type", new SimpleText( "human" ) );
doc4.addUserDefinedField( "data/person/gender", "male" );
doc4.addUserDefinedField( "data/person/age", new SimpleText( "37" ) );
doc4.addUserDefinedField( "data/person/food", new SimpleText( "sushi" ) );
doc4.addUserDefinedField( "data/person/drink", "beer" );
contentIndexService.index( doc4 );
ContentDocument doc5 = new ContentDocument( new ContentKey( 5 ) );
setMetadata( date, doc5 );
doc5.setTitle( "Zorg" );
doc5.addUserDefinedField( "data/person/type", new SimpleText( "alien" ) );
doc5.addUserDefinedField( "data/person/gender", "male" );
doc5.addUserDefinedField( "data/person/age", new SimpleText( "79" ) );
doc5.addUserDefinedField( "data/person/food", new SimpleText( "humans" ) );
doc5.addUserDefinedField( "data/person/drink", "beer" );
contentIndexService.index( doc5 );
ContentDocument doc6 = new ContentDocument( new ContentKey( 6 ) );
setMetadata( date, doc6 );
doc6.setTitle( "Vampira" );
doc6.addUserDefinedField( "data/person/type", new SimpleText( "human" ) );
doc6.addUserDefinedField( "data/person/gender", "female" );
doc6.addUserDefinedField( "data/person/age", new SimpleText( "729" ) );
doc6.addUserDefinedField( "data/person/food", new SimpleText( "Shells" ) );
doc6.addUserDefinedField( "data/person/drink", "blood" );
contentIndexService.index( doc6 );
flushIndex();
}
protected ContentDocument createContentDocument( ContentKey contentKey, CategoryKey categoryKey, ContentTypeKey contentTypeKey,
String title, List<UserDefinedField> userDefinedFields )
{
ContentDocument doc = new ContentDocument( contentKey );
doc.setCategoryKey( categoryKey );
doc.setContentTypeKey( contentTypeKey );
doc.setContentTypeName( "Article" );
if ( title != null )
{
doc.setTitle( title );
}
for ( UserDefinedField userDefinedField : userDefinedFields )
{
doc.addUserDefinedField( userDefinedField );
}
doc.setStatus( 2 );
doc.setPriority( 0 );
return doc;
}
}