├── LICENSE.txt ├── NestedDocs1.class ├── NestedDocs1.java ├── NestedDocs2.class ├── NestedDocs2.java ├── README.txt ├── jc.sh ├── jr1.sh ├── jr2.sh ├── lib ├── commons-io-2.3.jar ├── httpclient-4.3.1.jar ├── httpcore-4.3.jar ├── httpmime-4.3.1.jar ├── jcl-over-slf4j-1.7.6.jar ├── noggit-0.5.jar ├── slf4j-api-1.7.6.jar ├── solr-core-4.9.0.jar ├── solr-solrj-4.9.0.jar ├── wstx-asl-3.2.7.jar └── zookeeper-3.4.6.jar ├── sample-output1.txt └── sample-output2.txt /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ASL 2.0 2 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 3 | 4 | You may obtain a copy of the License at: 5 | http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | 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. 8 | -------------------------------------------------------------------------------- /NestedDocs1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/NestedDocs1.class -------------------------------------------------------------------------------- /NestedDocs1.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Collection; 3 | import java.util.Map.Entry; 4 | import org.apache.solr.client.solrj.SolrQuery; 5 | import org.apache.solr.client.solrj.impl.HttpSolrServer; 6 | import org.apache.solr.client.solrj.response.QueryResponse; 7 | import org.apache.solr.common.SolrDocument; 8 | import org.apache.solr.common.SolrDocumentList; 9 | import org.apache.solr.common.SolrInputDocument; 10 | 11 | 12 | public class NestedDocs1 { 13 | 14 | static final String SOLR_URL = "http://localhost:8983/solr/collection1"; 15 | 16 | public static void main ( String[] args ) throws Exception { 17 | 18 | HttpSolrServer solr = new HttpSolrServer( SOLR_URL ); 19 | 20 | /*** 21 | Equivalent Solr XML doc: 22 | 23 | 24 | product01 25 | car 26 | product 27 | 28 | part01 29 | wheels 30 | part 31 | 32 | 33 | part02 34 | engine 35 | part 36 | 37 | 38 | part03 39 | brakes 40 | part 41 | 42 | 43 | 44 | product02 45 | truck 46 | product 47 | 48 | part04 49 | wheels 50 | part 51 | 52 | 53 | part05 54 | flaps 55 | part 56 | 57 | 58 | 59 | ***/ 60 | 61 | // Docs to submit 62 | Collection batch = new ArrayList(); 63 | 64 | // Parent Doc 1 65 | SolrInputDocument product01 = new SolrInputDocument(); 66 | product01.addField( "id", "product01" ); 67 | product01.addField( "name", "car" ); 68 | product01.addField( "content_type", "product" ); 69 | 70 | // 3 Children 71 | SolrInputDocument part01 = new SolrInputDocument(); 72 | part01.addField( "id", "part01" ); 73 | part01.addField( "name", "wheels" ); 74 | part01.addField( "content_type", "part" ); 75 | SolrInputDocument part02 = new SolrInputDocument(); 76 | part02.addField( "id", "part02" ); 77 | part02.addField( "name", "engine" ); 78 | part02.addField( "content_type", "part" ); 79 | SolrInputDocument part03 = new SolrInputDocument(); 80 | part03.addField( "id", "part03" ); 81 | part03.addField( "name", "brakes" ); 82 | part03.addField( "content_type", "part" ); 83 | 84 | // Add children to parent 85 | product01.addChildDocument( part01 ); 86 | product01.addChildDocument( part02 ); 87 | product01.addChildDocument( part03 ); 88 | 89 | //System.out.println( "product01 = " + product01 ); 90 | 91 | // Add parent to batch 92 | batch.add( product01 ); 93 | 94 | // Parent Doc 2 with 2 children 95 | SolrInputDocument product02 = new SolrInputDocument(); 96 | product02.addField( "id", "product02" ); 97 | product02.addField( "name", "truck" ); 98 | product02.addField( "content_type", "product" ); 99 | SolrInputDocument part04 = new SolrInputDocument(); 100 | part04.addField( "id", "part04" ); 101 | part04.addField( "name", "wheels" ); 102 | part04.addField( "content_type", "part" ); 103 | SolrInputDocument part05 = new SolrInputDocument(); 104 | part05.addField( "id", "part05" ); 105 | part05.addField( "name", "flaps" ); 106 | part05.addField( "content_type", "part" ); 107 | product02.addChildDocument( part04 ); 108 | product02.addChildDocument( part05 ); 109 | //System.out.println( "product02 = " + product02 ); 110 | batch.add( product02 ); 111 | 112 | System.out.println( "Adding batch of " + batch.size() + " parent docs" ); 113 | 114 | // Submit as a group 115 | solr.add( batch ); 116 | solr.commit(); 117 | 118 | // Run some Test Queries 119 | // doQuery( solrServer, qryDescription, qryTerms, optFilterQuery ) 120 | 121 | doQuery( solr, "Null Query, All Docs", 122 | "*:*", null ); 123 | 124 | // Products and Parts 125 | doQuery( solr, "All Products", 126 | "*:*", "content_type:product" ); 127 | doQuery( solr, "All Parts", 128 | "*:*", "content_type:part" ); 129 | 130 | // Wheels for Cars, returning Parts 131 | // want part01 "car / wheels" 132 | // but not part04 "truck / wheels" 133 | // Return Children: 134 | // ?q=childTerm&fq={!child of="doctype:parent"}parentTerm 135 | doQuery( solr, "Wheels for Cars", 136 | "name:wheels", "{!child of=\"content_type:product\"}name:car" ); 137 | 138 | // Products that have Mud Flaps, AKA "flaps" 139 | // want product02 from "track / flaps" 140 | // Return Parents: 141 | // ?q=parentTerm&fq={!parent which="doctype:parent"}childTerm 142 | doQuery( solr, "Products with Flaps", 143 | "*:*", "{!parent which=\"content_type:product\"}name:flaps" ); 144 | 145 | } 146 | 147 | static void doQuery( HttpSolrServer solr, String description, String queryStr, String optFilter ) throws Exception { 148 | // Setup Query 149 | SolrQuery q = new SolrQuery( queryStr ); 150 | System.out.println(); 151 | System.out.println( "Running query: " + description ); 152 | System.out.print ( " with: " + queryStr ); 153 | if ( null!=optFilter ) { 154 | q.addFilterQuery( optFilter ); 155 | System.out.print( ", Filter: " + optFilter ); 156 | } 157 | System.out.println(); 158 | 159 | // Run and show results 160 | QueryResponse rsp = solr.query( q ); 161 | SolrDocumentList docs = rsp.getResults(); 162 | long numFound = docs.getNumFound(); 163 | System.out.println( "Matched: " + numFound ); 164 | int docCounter = 0; 165 | for (SolrDocument doc : docs) { 166 | docCounter++; 167 | System.out.println( "Doc # " + docCounter ); 168 | for ( Entry field : doc.entrySet() ) { 169 | String name = field.getKey(); 170 | Object value = field.getValue(); 171 | System.out.println( "\t" + name + "=" + value ); 172 | } 173 | } 174 | } 175 | 176 | } 177 | -------------------------------------------------------------------------------- /NestedDocs2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/NestedDocs2.class -------------------------------------------------------------------------------- /NestedDocs2.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Collection; 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.Map.Entry; 6 | import java.util.LinkedHashMap; 7 | import org.apache.solr.client.solrj.SolrQuery; 8 | import org.apache.solr.client.solrj.impl.HttpSolrServer; 9 | import org.apache.solr.client.solrj.response.QueryResponse; 10 | import org.apache.solr.common.SolrDocument; 11 | import org.apache.solr.common.SolrDocumentList; 12 | import org.apache.solr.common.SolrInputDocument; 13 | 14 | 15 | public class NestedDocs2 { 16 | 17 | static final String SOLR_URL = "http://localhost:8983/solr/collection1"; 18 | 19 | // IMPORTANT: This demo requires Solr 4.9.0 or above 20 | 21 | public static void main ( String[] args ) throws Exception { 22 | 23 | HttpSolrServer solr = new HttpSolrServer( SOLR_URL ); 24 | 25 | /* 26 | Goals of this demo: 27 | - Index the nested documents 28 | - Be able to do normal queries 29 | - Use parent / child Block Joins in queries 30 | - Be able to query for either parent or child records 31 | - Get nested query results with both record types using the [child] Transformer 32 | (this is new in Solr 4.9.0) 33 | - Use eDismax to alter the relevancy 34 | - Show how to use custom parameters 35 | - Show the full Solr URL to allow for easy edits and testing 36 | 37 | 38 | Consider an XML stream of the form: 39 | 40 | 41 | John 42 | Jones 43 | ...other details... 44 | 45 | 46 | honda 47 | accord 48 | 49 | 50 | Nissan 51 | Maxima 52 | 53 | 54 | 55 | 56 | yamaha 57 | passion 58 | 59 | 60 | Peugeot 61 | Vivacity 62 | 63 | 64 | 65 | 66 | Satish 67 | Smith 68 | 69 | 70 | Peugeot 71 | iOn 72 | 73 | 74 | 75 | 76 | Honda 77 | Spree 78 | 79 | 80 | 81 | 82 | ... 83 | 84 | 85 | 86 | Summary of the Parent/Child objects: 87 | John Jones 88 | car: Honda Accord 89 | car: Nissan Maxima 90 | bike: Yamaha Passion 91 | bike: Peugeot Vivacity 92 | Satish Smith 93 | car: Peugeot iOn 94 | bike: Honda Spree 95 | 96 | We then submit this data via SolrJ, using nested SolrInputDocument objects. 97 | 98 | Then run queries and show results. 99 | 100 | TODO: maybe add code that shows converting from XML to SolrJ 101 | 102 | */ 103 | 104 | 105 | // Docs to submit 106 | Collection batch = new ArrayList(); 107 | 108 | // Parent Doc 1, a person mamed John Jones 109 | SolrInputDocument person1 = new SolrInputDocument(); 110 | person1.addField( "id", "john_jones" ); 111 | person1.addField( "content_type", "person" ); 112 | // "_t" suffix tells Solr that it's text 113 | person1.addField( "first_name_t", "John" ); 114 | person1.addField( "last_name_t", "Jones" ); 115 | // states and history used in edismax examples 116 | person1.addField( "states_t", "California Nevada Idaho Maine" ); 117 | person1.addField( "history_t", "safe accident accident accident accident accident" ); 118 | 119 | // child docs, the vehicles he owns 120 | SolrInputDocument p1_car1 = new SolrInputDocument(); 121 | p1_car1.addField( "id", "jj_car1" ); 122 | p1_car1.addField( "content_type", "car" ); 123 | // For cars "make" is an alias for "manufacturer" 124 | p1_car1.addField( "make_t", "Honda" ); 125 | p1_car1.addField( "model_t", "Accord" ); 126 | 127 | SolrInputDocument p1_car2 = new SolrInputDocument(); 128 | p1_car2.addField( "id", "jj_car2" ); 129 | p1_car2.addField( "content_type", "car" ); 130 | p1_car2.addField( "make_t", "Nissan" ); 131 | p1_car2.addField( "model_t", "Maxima" ); 132 | 133 | SolrInputDocument p1_bike1 = new SolrInputDocument(); 134 | p1_bike1.addField( "id", "jj_bike1" ); 135 | p1_bike1.addField( "content_type", "bike" ); 136 | p1_bike1.addField( "make_t", "Yamaha" ); 137 | p1_bike1.addField( "model_t", "Passion" ); 138 | 139 | SolrInputDocument p1_bike2 = new SolrInputDocument(); 140 | p1_bike2.addField( "id", "jj_bike2" ); 141 | p1_bike2.addField( "content_type", "bike" ); 142 | p1_bike2.addField( "make_t", "Peugeot" ); 143 | p1_bike2.addField( "model_t", "Vivacity" ); 144 | 145 | // Add children to parent 146 | person1.addChildDocument( p1_car1 ); 147 | person1.addChildDocument( p1_car2 ); 148 | person1.addChildDocument( p1_bike1 ); 149 | person1.addChildDocument( p1_bike2 ); 150 | 151 | // Add parent to batch 152 | batch.add( person1 ); 153 | 154 | 155 | // Parent Doc 2, person mamed Satish Smith 156 | SolrInputDocument person2 = new SolrInputDocument(); 157 | person2.addField( "id", "satish_smith" ); 158 | person2.addField( "content_type", "person" ); 159 | person2.addField( "first_name_t", "Satish" ); 160 | person2.addField( "last_name_t", "Smith" ); 161 | person2.addField( "states_t", "California Texas California Maine Vermont Connecticut" ); 162 | person2.addField( "history_t", "safe safe safe safe safe safe safe safe accident" ); 163 | 164 | // Vehicles (child docs) 165 | SolrInputDocument p2_car1 = new SolrInputDocument(); 166 | p2_car1.addField( "id", "ss_car1" ); 167 | p2_car1.addField( "content_type", "car" ); 168 | p2_car1.addField( "make_t", "Peugeot" ); 169 | p2_car1.addField( "model_t", "iOn" ); 170 | SolrInputDocument p2_bike1 = new SolrInputDocument(); 171 | p2_bike1.addField( "id", "ss_bike1" ); 172 | p2_bike1.addField( "content_type", "bike" ); 173 | p2_bike1.addField( "make_t", "Honda" ); 174 | p2_bike1.addField( "model_t", "Spree" ); 175 | // link objects and add to batch 176 | person2.addChildDocument( p2_car1 ); 177 | person2.addChildDocument( p2_bike1 ); 178 | batch.add( person2 ); 179 | 180 | System.out.println( "Adding batch of " + batch.size() + " parent docs" ); 181 | 182 | // Submit as a group 183 | solr.add( batch ); 184 | solr.commit(); 185 | 186 | // Run some Test Queries 187 | 188 | // doQuery( solrServer, qryDescription, qryTerms, optFilterQuery ) 189 | doQuery( solr, "Null Query, All Docs", 190 | "*:*", null ); 191 | 192 | // People and their Vehicles 193 | doQuery( solr, "All People", 194 | "*:*", "content_type:person" ); 195 | doQuery( solr, "All Cars", 196 | "*:*", "content_type:car" ); 197 | doQuery( solr, "All Bikes", 198 | "*:*", "content_type:bike" ); 199 | 200 | /*** 201 | Repeating sample data outline here: 202 | John Jones 203 | car: Honda Accord 204 | car: Nissan Maxima 205 | bike: Yamaha Passion 206 | bike: Peugeot Vivacity 207 | Satish Smith 208 | car: Peugeot iOn 209 | bike: Honda Spree 210 | ***/ 211 | 212 | // Any person who owns a Honda car AND a Peugeot bike 213 | // but NOT Honda bike nor Peugeot car, so not Satish Smith 214 | // We're retrieving parent docs (people) 215 | // but most of the search logic is against child docs (vehicles) 216 | doQuery(solr, 217 | "People who own both a Honda *car* and a Peugeot *bike*", 218 | "*:*", 219 | "{!parent which=\"content_type:person\"}" 220 | + "(content_type:car AND make_t:Honda)" 221 | + " OR (content_type:bike AND make_t:Peugeot)"); 222 | 223 | // All Cars owned by Mr. Jones 224 | // We're retrieving child docs (cars) 225 | // but the fulltext search is against parent docs (people) 226 | doQuery(solr, 227 | "All cars owned by Mr. Jones", 228 | "content_type:car", 229 | "{!child of=\"content_type:person\"}last_name_t:jones"); 230 | 231 | // Show how to get merged Parent and Child records 232 | // ----------------------------------------------- 233 | 234 | // Any person who owns a Honda car AND a Peugeot bike 235 | // and include the matching vehicles as children, 236 | // but *only* the *matching* children. 237 | // This uses the [child ...] doc Transformer that appeared in Solr 4.9.0 238 | Map params = new LinkedHashMap<>(); 239 | params.put( "parent_filter", "content_type:person" ); 240 | params.put( "child_filter", 241 | "(content_type:car AND make_t:Honda)" 242 | + " OR (content_type:bike AND make_t:Peugeot)" ); 243 | // Use second form of doQuery to pass more arguments: 244 | // doQuery( solr, description, queryStr, optFilter, optFields, extraParamsMap ) 245 | doQuery(solr, 246 | "People who own a Honda car and Peugeot bike, and include the *matching* vehicles in results", 247 | "*:*", // query 248 | "{!parent which=$parent_filter v=$child_filter}", // filter 249 | "*,[child parentFilter=$parent_filter childFilter=$child_filter]", // fields 250 | params ); // extra params 251 | 252 | // Also, try some fancy queries with eDismax 253 | // ----------------------------------------- 254 | 255 | // eDismax1: Drivers matching accidents and/or California, no joins 256 | // dismax and edismax are similar, "e" is for "Enhanced" 257 | // John Jones will be listed first, "accident" appears many times in his history 258 | /*Map*/ params = new LinkedHashMap<>(); 259 | params.put( "defType", "edismax" ); 260 | params.put( "qf", "history_t states_t" ); // query fields 261 | doQuery(solr, 262 | "eDismax1: Drivers matching accidents and/or California, no joins", 263 | "California accident report", 264 | null, null, params); 265 | 266 | // eDismax2: Drivers matching accidents in California, stressing the State 267 | // Satish Smith will be listed first, since he's lived in California twice 268 | /*Map*/ params = new LinkedHashMap<>(); 269 | params.put( "defType", "edismax" ); 270 | params.put( "qf", "history_t states_t^100" ); // query fields 271 | doQuery(solr, 272 | "eDismax2: Drivers matching accidents and/or California, no joins, boost on State", 273 | "California accident report", 274 | null, null, params); 275 | 276 | // eDismax + Parent / Child Join 277 | // ----------------------------- 278 | 279 | // eDismax3: Drivers matching accidents and/or California, favoring state 280 | // and include *all* of their vehicles (no childFilter this time) 281 | // John Jones will be listed first, accident appears many times in history 282 | /*Map*/ params = new LinkedHashMap<>(); 283 | params.put( "parent_filter", "content_type:person" ); 284 | params.put( "defType", "edismax" ); 285 | params.put( "qf", "history_t states_t^100" ); 286 | doQuery(solr, 287 | "eDismax3: Drivers matching accidents and/or California, and all of their vehicles, boost on State", 288 | "California accident report", 289 | "{!parent which=$parent_filter}", 290 | "*,[child parentFilter=$parent_filter]", 291 | params ); 292 | 293 | } 294 | 295 | static void doQuery( HttpSolrServer solr, String description, String queryStr, String optFilter ) throws Exception { 296 | doQuery( solr, description, queryStr, optFilter, null, null ); 297 | } 298 | static void doQuery( HttpSolrServer solr, String description, String queryStr, String optFilter, 299 | String optFields, MapextraParams ) throws Exception { 300 | // Setup Query 301 | SolrQuery q = new SolrQuery( queryStr ); 302 | System.out.println(); 303 | System.out.println( "Test: " + description ); 304 | System.out.println( "\tSearch: " + queryStr ); 305 | if ( null!=optFilter ) { 306 | q.addFilterQuery( optFilter ); 307 | System.out.println( "\tFilter: " + optFilter ); 308 | } 309 | if ( null!=optFields ) { 310 | // Use setParam instead of addField 311 | q.setParam( "fl", optFields ); // childFilter=doc_type:chapter limit=100 312 | System.out.println( "\tFields: " + optFields ); 313 | } 314 | else { 315 | q.addField( "*" ); // childFilter=doc_type:chapter limit=100 316 | } 317 | if ( null!=extraParams ) { 318 | for ( Entry param : extraParams.entrySet() ) { 319 | // Could use q.setParam which allows you to pass in multiple strings 320 | q.set( param.getKey(), param.getValue() ); 321 | System.out.println( "\tParam: " + param.getKey() + "=" + param.getValue() ); 322 | } 323 | } 324 | 325 | // Run and show results 326 | QueryResponse rsp = solr.query( q ); 327 | SolrDocumentList docs = rsp.getResults(); 328 | long numFound = docs.getNumFound(); 329 | System.out.println( "Matched: " + numFound ); 330 | int docCounter = 0; 331 | for (SolrDocument doc : docs) { 332 | docCounter++; 333 | System.out.println( "Doc # " + docCounter ); 334 | for ( Entry field : doc.entrySet() ) { 335 | String name = field.getKey(); 336 | Object value = field.getValue(); 337 | System.out.println( "\t" + name + "=" + value ); 338 | } 339 | List childDocs = doc.getChildDocuments(); 340 | // TODO: make this recursive, for grandchildren, etc. 341 | if ( null!=childDocs ) { 342 | for ( SolrDocument child : childDocs ) { 343 | System.out.println( "\tChild doc:" ); 344 | for ( Entry field : child.entrySet() ) { 345 | String name = field.getKey(); 346 | Object value = field.getValue(); 347 | System.out.println( "\t\t" + name + "=" + value ); 348 | } 349 | } 350 | } 351 | } 352 | System.out.println( "Query URL:" ); 353 | // TODO: should check URL for existing trailing /, and allow for different query handler 354 | System.out.println( SOLR_URL + "/select?" + q ); 355 | } 356 | 357 | } 358 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Solr Nested Documents and Block Joins 2 | v0.2, 7/1/2014, mark dot bennett at lucidworks dot com 3 | 4 | Simple programs to demonstrate Parent / Child joins in Solr 5 | using the SolrJ API 6 | 7 | Requires: 8 | Java 1.7 or above 9 | Demo 1: Solr 4.5 or above; 4.9.0 used here 10 | Demo 2: Requires Solr 4.9.0 11 | Script assumes Unix Bash Shell 12 | could run on Windows if proper classpath is set 13 | 14 | Demo 1 vs. Demo 2 15 | Demo 1 shows basic joins 16 | Demo 2 goes further: 17 | - Index the nested documents 18 | - Be able to do normal queries 19 | - Use parent / child Block Joins in queries 20 | - Be able to query for either parent or child records 21 | - Get nested query results with both record types using the [child] Transformer 22 | (this is new in Solr 4.9.0) 23 | - Use eDismax to alter the relevancy 24 | - Show how to use custom parameters 25 | - Show the full Solr URL to allow for easy edits and testing 26 | 27 | Just want to look? 28 | Just view the files NestedDocs1 & 2.java and sample-output1 & 2.txt 29 | 30 | To actually run... 31 | 32 | Setup Solr: 33 | Download Solr (for example 4.9.0) 34 | Unzip / untar 35 | cd solr-4.9.0/example 36 | java -jar start.jar 37 | # Java code uses fields defined in the default schema.xml 38 | 39 | Run this example: 40 | Be in this main directory 41 | ./jr1.sh # jr = "java run" 42 | ./jr2.sh # second, fancier demo 43 | # Ignore warnings starting with "SLF4J: ...", this is just SolrJ logging nonsense. 44 | 45 | Recompile: 46 | This ships with compiled .class files 47 | But you can recompile with: 48 | ./jc.sh # jc = "java compile", compiles both demos 49 | Perhaps useful if you want to change the code 50 | or use older Solr or Java versions 51 | -------------------------------------------------------------------------------- /jc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | JAR=lib/solr-solrj-4.9.0.jar 4 | 5 | javac -classpath $JAR *.java 6 | -------------------------------------------------------------------------------- /jr1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | JARS=`echo lib/*.jar | sed -e 's/ /:/g'` 4 | CLASS=NestedDocs1 5 | 6 | java -cp ".:$JARS" $CLASS 7 | -------------------------------------------------------------------------------- /jr2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | JARS=`echo lib/*.jar | sed -e 's/ /:/g'` 4 | CLASS=NestedDocs2 5 | 6 | java -cp ".:$JARS" $CLASS 7 | -------------------------------------------------------------------------------- /lib/commons-io-2.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/commons-io-2.3.jar -------------------------------------------------------------------------------- /lib/httpclient-4.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/httpclient-4.3.1.jar -------------------------------------------------------------------------------- /lib/httpcore-4.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/httpcore-4.3.jar -------------------------------------------------------------------------------- /lib/httpmime-4.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/httpmime-4.3.1.jar -------------------------------------------------------------------------------- /lib/jcl-over-slf4j-1.7.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/jcl-over-slf4j-1.7.6.jar -------------------------------------------------------------------------------- /lib/noggit-0.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/noggit-0.5.jar -------------------------------------------------------------------------------- /lib/slf4j-api-1.7.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/slf4j-api-1.7.6.jar -------------------------------------------------------------------------------- /lib/solr-core-4.9.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/solr-core-4.9.0.jar -------------------------------------------------------------------------------- /lib/solr-solrj-4.9.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/solr-solrj-4.9.0.jar -------------------------------------------------------------------------------- /lib/wstx-asl-3.2.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/wstx-asl-3.2.7.jar -------------------------------------------------------------------------------- /lib/zookeeper-3.4.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucidworks/solrj-nested-docs/931099e7d9397e9b56dc6b7033cfdd10260ac48a/lib/zookeeper-3.4.6.jar -------------------------------------------------------------------------------- /sample-output1.txt: -------------------------------------------------------------------------------- 1 | Adding batch of 2 parent docs 2 | 3 | Running query: Null Query, All Docs 4 | with: *:* 5 | Matched: 7 6 | Doc # 1 7 | id=part01 8 | name=wheels 9 | content_type=[part] 10 | Doc # 2 11 | id=part02 12 | name=engine 13 | content_type=[part] 14 | Doc # 3 15 | id=part03 16 | name=brakes 17 | content_type=[part] 18 | Doc # 4 19 | id=product01 20 | name=car 21 | content_type=[product] 22 | _version_=1471220857287213056 23 | Doc # 5 24 | id=part04 25 | name=wheels 26 | content_type=[part] 27 | Doc # 6 28 | id=part05 29 | name=flaps 30 | content_type=[part] 31 | Doc # 7 32 | id=product02 33 | name=truck 34 | content_type=[product] 35 | _version_=1471220857291407360 36 | 37 | Running query: All Products 38 | with: *:*, Filter: content_type:product 39 | Matched: 2 40 | Doc # 1 41 | id=product01 42 | name=car 43 | content_type=[product] 44 | _version_=1471220857287213056 45 | Doc # 2 46 | id=product02 47 | name=truck 48 | content_type=[product] 49 | _version_=1471220857291407360 50 | 51 | Running query: All Parts 52 | with: *:*, Filter: content_type:part 53 | Matched: 5 54 | Doc # 1 55 | id=part01 56 | name=wheels 57 | content_type=[part] 58 | Doc # 2 59 | id=part02 60 | name=engine 61 | content_type=[part] 62 | Doc # 3 63 | id=part03 64 | name=brakes 65 | content_type=[part] 66 | Doc # 4 67 | id=part04 68 | name=wheels 69 | content_type=[part] 70 | Doc # 5 71 | id=part05 72 | name=flaps 73 | content_type=[part] 74 | 75 | Running query: Wheels for Cars 76 | with: name:wheels, Filter: {!child of="content_type:product"}name:car 77 | Matched: 1 78 | Doc # 1 79 | id=part01 80 | name=wheels 81 | content_type=[part] 82 | 83 | Running query: Products with Flaps 84 | with: *:*, Filter: {!parent which="content_type:product"}name:flaps 85 | Matched: 1 86 | Doc # 1 87 | id=product02 88 | name=truck 89 | content_type=[product] 90 | _version_=1471220857291407360 91 | -------------------------------------------------------------------------------- /sample-output2.txt: -------------------------------------------------------------------------------- 1 | Adding batch of 2 parent docs 2 | 3 | Test: Null Query, All Docs 4 | Search: *:* 5 | Matched: 15 6 | Doc # 1 7 | id=part01 8 | name=wheels 9 | content_type=[part] 10 | Doc # 2 11 | id=part02 12 | name=engine 13 | content_type=[part] 14 | Doc # 3 15 | id=part03 16 | name=brakes 17 | content_type=[part] 18 | Doc # 4 19 | id=product01 20 | name=car 21 | content_type=[product] 22 | _version_=1472484808421539840 23 | Doc # 5 24 | id=part04 25 | name=wheels 26 | content_type=[part] 27 | Doc # 6 28 | id=part05 29 | name=flaps 30 | content_type=[part] 31 | Doc # 7 32 | id=product02 33 | name=truck 34 | content_type=[product] 35 | _version_=1472484808424685568 36 | Doc # 8 37 | id=jj_car1 38 | content_type=[car] 39 | make_t=Honda 40 | model_t=Accord 41 | Doc # 9 42 | id=jj_car2 43 | content_type=[car] 44 | make_t=Nissan 45 | model_t=Maxima 46 | Doc # 10 47 | id=jj_bike1 48 | content_type=[bike] 49 | make_t=Yamaha 50 | model_t=Passion 51 | Query URL: 52 | http://localhost:8983/solr/collection1/select?q=*%3A*&fl=* 53 | 54 | Test: All People 55 | Search: *:* 56 | Filter: content_type:person 57 | Matched: 2 58 | Doc # 1 59 | id=john_jones 60 | content_type=[person] 61 | first_name_t=John 62 | last_name_t=Jones 63 | states_t=California Nevada Idaho Maine 64 | history_t=safe accident accident accident accident accident 65 | _version_=1472484842236018688 66 | Doc # 2 67 | id=satish_smith 68 | content_type=[person] 69 | first_name_t=Satish 70 | last_name_t=Smith 71 | states_t=California Texas California Maine Vermont Connecticut 72 | history_t=safe safe safe safe safe safe safe safe accident 73 | _version_=1472484842239164416 74 | Query URL: 75 | http://localhost:8983/solr/collection1/select?q=*%3A*&fq=content_type%3Aperson&fl=* 76 | 77 | Test: All Cars 78 | Search: *:* 79 | Filter: content_type:car 80 | Matched: 3 81 | Doc # 1 82 | id=jj_car1 83 | content_type=[car] 84 | make_t=Honda 85 | model_t=Accord 86 | Doc # 2 87 | id=jj_car2 88 | content_type=[car] 89 | make_t=Nissan 90 | model_t=Maxima 91 | Doc # 3 92 | id=ss_car1 93 | content_type=[car] 94 | make_t=Peugeot 95 | model_t=iOn 96 | Query URL: 97 | http://localhost:8983/solr/collection1/select?q=*%3A*&fq=content_type%3Acar&fl=* 98 | 99 | Test: All Bikes 100 | Search: *:* 101 | Filter: content_type:bike 102 | Matched: 3 103 | Doc # 1 104 | id=jj_bike1 105 | content_type=[bike] 106 | make_t=Yamaha 107 | model_t=Passion 108 | Doc # 2 109 | id=jj_bike2 110 | content_type=[bike] 111 | make_t=Peugeot 112 | model_t=Vivacity 113 | Doc # 3 114 | id=ss_bike1 115 | content_type=[bike] 116 | make_t=Honda 117 | model_t=Spree 118 | Query URL: 119 | http://localhost:8983/solr/collection1/select?q=*%3A*&fq=content_type%3Abike&fl=* 120 | 121 | Test: People who own both a Honda *car* and a Peugeot *bike* 122 | Search: *:* 123 | Filter: {!parent which="content_type:person"}(content_type:car AND make_t:Honda) OR (content_type:bike AND make_t:Peugeot) 124 | Matched: 1 125 | Doc # 1 126 | id=john_jones 127 | content_type=[person] 128 | first_name_t=John 129 | last_name_t=Jones 130 | states_t=California Nevada Idaho Maine 131 | history_t=safe accident accident accident accident accident 132 | _version_=1472484842236018688 133 | Query URL: 134 | http://localhost:8983/solr/collection1/select?q=*%3A*&fq=%7B%21parent+which%3D%22content_type%3Aperson%22%7D%28content_type%3Acar+AND+make_t%3AHonda%29+OR+%28content_type%3Abike+AND+make_t%3APeugeot%29&fl=* 135 | 136 | Test: All cars owned by Mr. Jones 137 | Search: content_type:car 138 | Filter: {!child of="content_type:person"}last_name_t:jones 139 | Matched: 2 140 | Doc # 1 141 | id=jj_car1 142 | content_type=[car] 143 | make_t=Honda 144 | model_t=Accord 145 | Doc # 2 146 | id=jj_car2 147 | content_type=[car] 148 | make_t=Nissan 149 | model_t=Maxima 150 | Query URL: 151 | http://localhost:8983/solr/collection1/select?q=content_type%3Acar&fq=%7B%21child+of%3D%22content_type%3Aperson%22%7Dlast_name_t%3Ajones&fl=* 152 | 153 | Test: People who own a Honda car and Peugeot bike, and include the *matching* vehicles in results 154 | Search: *:* 155 | Filter: {!parent which=$parent_filter v=$child_filter} 156 | Fields: *,[child parentFilter=$parent_filter childFilter=$child_filter] 157 | Param: parent_filter=content_type:person 158 | Param: child_filter=(content_type:car AND make_t:Honda) OR (content_type:bike AND make_t:Peugeot) 159 | Matched: 1 160 | Doc # 1 161 | id=john_jones 162 | content_type=[person] 163 | first_name_t=John 164 | last_name_t=Jones 165 | states_t=California Nevada Idaho Maine 166 | history_t=safe accident accident accident accident accident 167 | _version_=1472484842236018688 168 | Child doc: 169 | id=jj_car1 170 | content_type=[car] 171 | make_t=Honda 172 | model_t=Accord 173 | Child doc: 174 | id=jj_bike2 175 | content_type=[bike] 176 | make_t=Peugeot 177 | model_t=Vivacity 178 | Query URL: 179 | http://localhost:8983/solr/collection1/select?q=*%3A*&fq=%7B%21parent+which%3D%24parent_filter+v%3D%24child_filter%7D&fl=*%2C%5Bchild+parentFilter%3D%24parent_filter+childFilter%3D%24child_filter%5D&parent_filter=content_type%3Aperson&child_filter=%28content_type%3Acar+AND+make_t%3AHonda%29+OR+%28content_type%3Abike+AND+make_t%3APeugeot%29 180 | 181 | Test: eDismax1: Drivers matching accidents and/or California, no joins 182 | Search: California accident report 183 | Param: defType=edismax 184 | Param: qf=history_t states_t 185 | Matched: 2 186 | Doc # 1 187 | id=john_jones 188 | content_type=[person] 189 | first_name_t=John 190 | last_name_t=Jones 191 | states_t=California Nevada Idaho Maine 192 | history_t=safe accident accident accident accident accident 193 | _version_=1472484842236018688 194 | Doc # 2 195 | id=satish_smith 196 | content_type=[person] 197 | first_name_t=Satish 198 | last_name_t=Smith 199 | states_t=California Texas California Maine Vermont Connecticut 200 | history_t=safe safe safe safe safe safe safe safe accident 201 | _version_=1472484842239164416 202 | Query URL: 203 | http://localhost:8983/solr/collection1/select?q=California+accident+report&fl=*&defType=edismax&qf=history_t+states_t 204 | 205 | Test: eDismax2: Drivers matching accidents and/or California, no joins, boost on State 206 | Search: California accident report 207 | Param: defType=edismax 208 | Param: qf=history_t states_t^100 209 | Matched: 2 210 | Doc # 1 211 | id=satish_smith 212 | content_type=[person] 213 | first_name_t=Satish 214 | last_name_t=Smith 215 | states_t=California Texas California Maine Vermont Connecticut 216 | history_t=safe safe safe safe safe safe safe safe accident 217 | _version_=1472484842239164416 218 | Doc # 2 219 | id=john_jones 220 | content_type=[person] 221 | first_name_t=John 222 | last_name_t=Jones 223 | states_t=California Nevada Idaho Maine 224 | history_t=safe accident accident accident accident accident 225 | _version_=1472484842236018688 226 | Query URL: 227 | http://localhost:8983/solr/collection1/select?q=California+accident+report&fl=*&defType=edismax&qf=history_t+states_t%5E100 228 | 229 | Test: eDismax3: Drivers matching accidents and/or California, and all of their vehicles, boost on State 230 | Search: California accident report 231 | Filter: {!parent which=$parent_filter} 232 | Fields: *,[child parentFilter=$parent_filter] 233 | Param: parent_filter=content_type:person 234 | Param: defType=edismax 235 | Param: qf=history_t states_t^100 236 | Matched: 2 237 | Doc # 1 238 | id=satish_smith 239 | content_type=[person] 240 | first_name_t=Satish 241 | last_name_t=Smith 242 | states_t=California Texas California Maine Vermont Connecticut 243 | history_t=safe safe safe safe safe safe safe safe accident 244 | _version_=1472484842239164416 245 | Child doc: 246 | id=ss_car1 247 | content_type=[car] 248 | make_t=Peugeot 249 | model_t=iOn 250 | Child doc: 251 | id=ss_bike1 252 | content_type=[bike] 253 | make_t=Honda 254 | model_t=Spree 255 | Doc # 2 256 | id=john_jones 257 | content_type=[person] 258 | first_name_t=John 259 | last_name_t=Jones 260 | states_t=California Nevada Idaho Maine 261 | history_t=safe accident accident accident accident accident 262 | _version_=1472484842236018688 263 | Child doc: 264 | id=jj_car1 265 | content_type=[car] 266 | make_t=Honda 267 | model_t=Accord 268 | Child doc: 269 | id=jj_car2 270 | content_type=[car] 271 | make_t=Nissan 272 | model_t=Maxima 273 | Child doc: 274 | id=jj_bike1 275 | content_type=[bike] 276 | make_t=Yamaha 277 | model_t=Passion 278 | Child doc: 279 | id=jj_bike2 280 | content_type=[bike] 281 | make_t=Peugeot 282 | model_t=Vivacity 283 | Query URL: 284 | http://localhost:8983/solr/collection1/select?q=California+accident+report&fq=%7B%21parent+which%3D%24parent_filter%7D&fl=*%2C%5Bchild+parentFilter%3D%24parent_filter%5D&parent_filter=content_type%3Aperson&defType=edismax&qf=history_t+states_t%5E100 285 | --------------------------------------------------------------------------------