com.sindicetech.siren.solr.facet.TestSirenFacetProcessorFactory.java Source code

Java tutorial

Introduction

Here is the source code for com.sindicetech.siren.solr.facet.TestSirenFacetProcessorFactory.java

Source

/**
 * Copyright (c) 2014, Sindice Limited. All Rights Reserved.
 *
 * This file is part of the SIREn project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sindicetech.siren.solr.facet;

import java.io.File;

import org.apache.commons.io.FileUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.schema.IndexSchema;
import org.junit.BeforeClass;

import com.sindicetech.siren.solr.UpdateProcessorTestBase;
import com.sindicetech.siren.solr.facet.FacetDatatype;
import com.sindicetech.siren.solr.facet.SirenFacetProcessorFactory;
import com.sindicetech.siren.solr.facet.TypeMapping;

/**
 * Tests for generating Facets for Siren JSON fields.
 * 
 * WARNING: be careful about implementing new tests as the schema is NOT cleaned in between 
 * individual tests.
 */
public class TestSirenFacetProcessorFactory extends UpdateProcessorTestBase {

    @BeforeClass
    private static void initManagedSchemaCore() throws Exception {
        /* Create temporary solrHome folder in the target/ folder for this test because it
         * creates the managed-schema file which we don't want in src/main/resources/...
         * and it renames the original schema-*.xml to schema-*.xml.bak - also undesirable.
         * 
         * The {@link SolrServerTestCase}, extended by UpdateProcessorTestBase, takes care of
         * keeping the schema clean between individual test runs. 
         * 
         * We don't remove the temporary solrHome folder because it will be cleaned later by 
         * mvn clean anyway (and perhaps more reliably, e.g. on Windows, etc.).
         */
        File tempSolrHome = new File("target" + File.separator
                + TestSirenFacetProcessorFactory.class.getSimpleName() + System.currentTimeMillis());

        FileUtils.copyDirectory(new File(SOLR_HOME), tempSolrHome);
        // make the dir easier to find by time, otherwise it would have last modified time of 
        // the original SOLR_HOME
        tempSolrHome.setLastModified(System.currentTimeMillis());

        initCore("solrconfig-facets.xml", "schema-facets.xml", tempSolrHome.getAbsolutePath());
    }

    public void testStringField() throws Exception {
        String json = "{\"knows\": [{\"name\":\"josef\"}, {\"name\":\"szymon\"}]}";

        IndexSchema schema = h.getCore().getLatestSchema();

        SolrInputDocument d = processAdd("generate-facets-processor", doc(f("id", "1"), f("json", json)));
        assertNotNull(d);
        schema = h.getCore().getLatestSchema();
        assertNotNull(schema.getFieldOrNull("string.json.knows.name"));
        assertEquals("string", schema.getFieldType("string.json.knows.name").getTypeName());

        json = "{\"knows\": [{\"name\": null}]}";

        d = processAdd("generate-facets-processor", doc(f("id", "2"), f("json", json)));
        assertNotNull(d);
        schema = h.getCore().getLatestSchema();
        assertNotNull(schema.getFieldOrNull("string.json.knows.name"));
        assertEquals("string", schema.getFieldType("string.json.knows.name").getTypeName());

        json = "{\"knows\": {\"name\": true}}";

        d = processAdd("generate-facets-processor", doc(f("id", "3"), f("json", json)));
        assertNotNull(d);
        schema = h.getCore().getLatestSchema();
        assertNotNull(schema.getFieldOrNull("string.json.knows.name"));
        assertEquals("string", schema.getFieldType("string.json.knows.name").getTypeName());

        json = "{\"age\": 1}";

        d = processAdd("generate-facets-processor", doc(f("id", "4"), f("json", json)));
        assertNotNull(d);
        schema = h.getCore().getLatestSchema();
        assertNotNull(schema.getFieldOrNull("long.json.age"));
        assertEquals("tlong", schema.getFieldType("long.json.age").getTypeName());

        json = "{\"length\": 18.9}";

        d = processAdd("generate-facets-processor", doc(f("id", "5"), f("json", json)));
        assertNotNull(d);
        schema = h.getCore().getLatestSchema();
        assertNotNull(schema.getFieldOrNull("double.json.length"));
        assertEquals("tdouble", schema.getFieldType("double.json.length").getTypeName());

        // no facets should be generated for fields with values longer than SirenFacetProcessor.MAX_FACET_VALUE_LENGTH
        String tooLongValue = "Every night and every morn Some to misery are born, "
                + "Every morn and every night Some are born to sweet delight. Some are born to sweet"
                + " delight, Some are born to endless night.";
        json = "{\"description\": \"" + tooLongValue + "\"}";

        SirenFacetProcessorFactory factory = (SirenFacetProcessorFactory) h.getCore()
                .getUpdateProcessingChain("generate-facets-processor").getFactories()[0];
        TypeMapping stringTypeMapping = factory.getTypeMappingValueClass(FacetDatatype.STRING.xsdDatatype);
        assertTrue("Bad test. Test value has to be longer than maxFieldSize for TypeMapping of string = "
                + stringTypeMapping.maxFieldSize + " but its length is only " + tooLongValue.length()
                + ". You should check the size of "
                + "SirenFacetProcessor.DEFAULT_MAX_FACET_VALUE_LENGTH or solrconfig*.xml for the maxFieldSize setting of the string typeMapping "
                + " of the updateRequestProcessorChain", tooLongValue.length() > stringTypeMapping.maxFieldSize);

        d = processAdd("generate-facets-processor", doc(f("id", "6"), f("json", json)));
        assertNotNull(d);
        schema = h.getCore().getLatestSchema();
        assertNull(schema.getFieldOrNull("string.json.description"));
        assertNull(d.getFieldValue("string.json.description"));

    }

    public void testCustomDatatypeField() throws Exception {
        String json = "{\"rating\": {\"_datatype_\": \"http://www.w3.org/2001/XMLSchema#double\", \"_value_\":\"5.4\"}}";

        IndexSchema schema = h.getCore().getLatestSchema();

        SolrInputDocument d = processAdd("generate-facets-processor", doc(f("id", "1"), f("json", json)));
        assertNotNull(d);
        schema = h.getCore().getLatestSchema();
        assertNotNull(schema.getFieldOrNull("double.json.rating"));
        assertEquals("tdouble", schema.getFieldType("double.json.rating").getTypeName());
        assertTrue((5.4 - (double) d.getFieldValue("double.json.rating")) < 0.01);

        getWrapper().add(d); // add so that we can test facets by querying
        this.commit();

        SolrQuery q = new SolrQuery();
        q.setRequestHandler("keyword");
        q.setParam("nested", "{!lucene} *:*");
        q.setFacet(true);
        q.addFacetField("double.json.rating");
        QueryResponse r = getWrapper().getServer().query(q);
        // we know there is only one facet field with one value
        assertEquals(1, r.getFacetFields().get(0).getValues().get(0).getCount());

        json = "{\"rating\": {\"_datatype_\": \"http://www.w3.org/2001/XMLSchema#float\", \"_value_\":\"-8.4\"}}";
        schema = h.getCore().getLatestSchema();
        d = processAdd("generate-facets-processor", doc(f("id", "2"), f("json", json)));
        assertNotNull(d);
        schema = h.getCore().getLatestSchema();
        assertNotNull(schema.getFieldOrNull("double.json.rating"));
        assertEquals("tdouble", schema.getFieldType("double.json.rating").getTypeName());
        assertTrue((-8.4 + (double) d.getFieldValue("double.json.rating")) < 0.01);

        getWrapper().add(d); // add so that we can test facets by querying
        this.commit();

        r = getWrapper().getServer().query(q);

        // there is only one facet field with two different values each with a single count
        assertEquals(1, r.getFacetFields().get(0).getValues().get(0).getCount());
        assertEquals(1, r.getFacetFields().get(0).getValues().get(1).getCount());
    }
}