blob: 566819b822c5da5086088cf4f435a452f2f978e8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.solr.client.ref_guide_examples;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.cloud.SolrCloudTestCase;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.util.ExternalPaths;
import org.junit.After;
import org.junit.BeforeClass;
/**
* Example SolrJ usage for indexing nested documents
*
* Snippets surrounded by "tag" and "end" comments are extracted and used in the Solr Reference Guide.
*/
public class IndexingNestedDocuments extends SolrCloudTestCase {
public static final String ANON_KIDS_CONFIG = "anon_kids_configset";
@BeforeClass
public static void setupCluster() throws Exception {
configureCluster(1)
// when indexing 'anonymous' kids, we need a schema that doesn't use _nest_path_ so
// that we can use [child] transformer with a parentFilter...
.addConfig(ANON_KIDS_CONFIG, new File(ExternalPaths.TECHPRODUCTS_CONFIGSET).toPath())
.configure();
}
@After
public void cleanCollections() throws Exception {
cluster.deleteAllCollections();
}
/**
* Syntactic sugar so code snippet doesn't refer to test-framework specific method name
*/
public static SolrClient getSolrClient() {
return cluster.getSolrClient();
}
/**
* Demo of using anonymous children when indexing hierarchical documents.
* This test code is used as an 'include' from the ref-guide
*/
public void testIndexingAnonKids() throws Exception {
final String collection = "test_anon";
CollectionAdminRequest.createCollection(collection, ANON_KIDS_CONFIG, 1, 1)
.setPerReplicaState(SolrCloudTestCase.USE_PER_REPLICA_STATE)
.process(cluster.getSolrClient());
cluster.getSolrClient().setDefaultCollection(collection);
//
// DO NOT MODIFY THESE EXAMPLE DOCS WITH OUT MAKING THE SAME CHANGES TO THE JSON AND XML
// EQUIVILENT EXAMPLES IN 'indexing-nested-documents.adoc'
//
// tag::anon-kids[]
final SolrClient client = getSolrClient();
final SolrInputDocument p1 = new SolrInputDocument();
p1.setField("id", "P11!prod");
p1.setField("type_s", "PRODUCT");
p1.setField("name_s", "Swingline Stapler");
p1.setField("description_t", "The Cadillac of office staplers ...");
{
final SolrInputDocument s1 = new SolrInputDocument();
s1.setField("id", "P11!S21");
s1.setField("type_s", "SKU");
s1.setField("color_s", "RED");
s1.setField("price_i", 42);
{
final SolrInputDocument m1 = new SolrInputDocument();
m1.setField("id", "P11!D41");
m1.setField("type_s", "MANUAL");
m1.setField("name_s", "Red Swingline Brochure");
m1.setField("pages_i", 1);
m1.setField("content_t", "...");
s1.addChildDocument(m1);
}
final SolrInputDocument s2 = new SolrInputDocument();
s2.setField("id", "P11!S31");
s2.setField("type_s", "SKU");
s2.setField("color_s", "BLACK");
s2.setField("price_i", 3);
final SolrInputDocument m1 = new SolrInputDocument();
m1.setField("id", "P11!D51");
m1.setField("type_s", "MANUAL");
m1.setField("name_s", "Quick Reference Guide");
m1.setField("pages_i", 1);
m1.setField("content_t", "How to use your stapler ...");
final SolrInputDocument m2 = new SolrInputDocument();
m2.setField("id", "P11!D61");
m2.setField("type_s", "MANUAL");
m2.setField("name_s", "Warranty Details");
m2.setField("pages_i", 42);
m2.setField("content_t", "... lifetime guarantee ...");
p1.addChildDocuments(Arrays.asList(s1, s2, m1, m2));
}
client.add(p1);
// end::anon-kids[]
client.commit();
final SolrDocumentList docs = getSolrClient().query
(new SolrQuery("description_t:Cadillac").set("fl", "*,[child parentFilter='type_s:PRODUCT']")).getResults();
assertEquals(1, docs.getNumFound());
assertEquals("P11!prod", docs.get(0).getFieldValue("id"));
// [child] returns a flat list of all (anon) descendents
assertEquals(5, docs.get(0).getChildDocumentCount());
assertEquals(5, docs.get(0).getChildDocuments().size());
// flat list is depth first...
final SolrDocument red_stapler_brochure = docs.get(0).getChildDocuments().get(0);
assertEquals("P11!D41", red_stapler_brochure.getFieldValue("id"));
final SolrDocument red_stapler = docs.get(0).getChildDocuments().get(1);
assertEquals("P11!S21", red_stapler.getFieldValue("id"));
}
/**
* Demo of using <code>NestPath</code> related psuedo-fields when indexing hierarchical documents.
* This test code is used as an 'include' from the ref-guide
*/
public void testIndexingUsingNestPath() throws Exception {
final String collection = "test_anon";
CollectionAdminRequest.createCollection(collection, 1, 1).process(cluster.getSolrClient());
cluster.getSolrClient().setDefaultCollection(collection);
//
// DO NOT MODIFY THESE EXAMPLE DOCS WITH OUT MAKING THE SAME CHANGES TO THE JSON AND XML
// EQUIVILENT EXAMPLES IN 'indexing-nested-documents.adoc'
//
// tag::nest-path[]
final SolrClient client = getSolrClient();
final SolrInputDocument p1 = new SolrInputDocument();
p1.setField("id", "P11!prod");
p1.setField("name_s", "Swingline Stapler");
p1.setField("description_t", "The Cadillac of office staplers ...");
{
final SolrInputDocument s1 = new SolrInputDocument();
s1.setField("id", "P11!S21");
s1.setField("color_s", "RED");
s1.setField("price_i", 42);
{
final SolrInputDocument m1 = new SolrInputDocument();
m1.setField("id", "P11!D41");
m1.setField("name_s", "Red Swingline Brochure");
m1.setField("pages_i", 1);
m1.setField("content_t", "...");
s1.setField("manuals", m1);
}
final SolrInputDocument s2 = new SolrInputDocument();
s2.setField("id", "P11!S31");
s2.setField("color_s", "BLACK");
s2.setField("price_i", 3);
p1.setField("skus", Arrays.asList(s1, s2));
}
{
final SolrInputDocument m1 = new SolrInputDocument();
m1.setField("id", "P11!D51");
m1.setField("name_s", "Quick Reference Guide");
m1.setField("pages_i", 1);
m1.setField("content_t", "How to use your stapler ...");
final SolrInputDocument m2 = new SolrInputDocument();
m2.setField("id", "P11!D61");
m2.setField("name_s", "Warranty Details");
m2.setField("pages_i", 42);
m2.setField("content_t", "... lifetime guarantee ...");
p1.setField("manuals", Arrays.asList(m1, m2));
}
final SolrInputDocument p2 = new SolrInputDocument();
p2.setField("id", "P22!prod");
p2.setField("name_s", "Mont Blanc Fountain Pen");
p2.setField("description_t", "A Premium Writing Instrument ...");
{
final SolrInputDocument s1 = new SolrInputDocument();
s1.setField("id", "P22!S22");
s1.setField("color_s", "RED");
s1.setField("price_i", 89);
{
final SolrInputDocument m1 = new SolrInputDocument();
m1.setField("id", "P22!D42");
m1.setField("name_s", "Red Mont Blanc Brochure");
m1.setField("pages_i", 1);
m1.setField("content_t", "...");
s1.setField("manuals", m1);
}
final SolrInputDocument s2 = new SolrInputDocument();
s2.setField("id", "P22!S32");
s2.setField("color_s", "BLACK");
s2.setField("price_i", 67);
p2.setField("skus", Arrays.asList(s1, s2));
}
{
final SolrInputDocument m1 = new SolrInputDocument();
m1.setField("id", "P22!D52");
m1.setField("name_s", "How To Use A Pen");
m1.setField("pages_i", 42);
m1.setField("content_t", "Start by removing the cap ...");
p2.setField("manuals", m1);
}
client.add(Arrays.asList(p1, p2));
// end::nest-path[]
client.commit();
// Now a quick sanity check that the nest path is working properly...
final SolrDocumentList docs = getSolrClient().query
(new SolrQuery("description_t:Writing").set("fl", "*,[child]")).getResults();
assertEquals(1, docs.getNumFound());
assertEquals("P22!prod", docs.get(0).getFieldValue("id"));
assertEquals(1, docs.get(0).getFieldValues("manuals").size());
assertEquals(SolrDocument.class, docs.get(0).getFieldValues("manuals").iterator().next().getClass());
assertEquals(2, docs.get(0).getFieldValues("skus").size());
final List<Object> skus = new ArrayList<>(docs.get(0).getFieldValues("skus"));
assertEquals(SolrDocument.class, skus.get(0).getClass());
assertEquals(SolrDocument.class, skus.get(1).getClass());
final SolrDocument red_pen = (SolrDocument) skus.get(0);
assertEquals("P22!S22", red_pen.getFieldValue("id"));
assertEquals(1, red_pen.getFieldValues("manuals").size());
assertEquals(SolrDocument.class, red_pen.getFieldValues("manuals").iterator().next().getClass());
final SolrDocument red_pen_brochure = (SolrDocument) red_pen.getFieldValues("manuals").iterator().next();
assertEquals("P22!D42", red_pen_brochure.getFieldValue("id"));
}
}