diff --git a/pom.xml b/pom.xml
index caca522..f74e20f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-solr
- 3.1.0.BUILD-SNAPSHOT
+ 2.1.8.RELEASE
Spring Data Solr
Spring Data module providing support for Apache Solr repositories.
@@ -14,16 +14,16 @@
org.springframework.data.build
spring-data-parent
- 2.1.0.BUILD-SNAPSHOT
+ 1.9.8.RELEASE
+ DATASOLR
3.2.1
3.1
4.3.1
- 6.6.1
- 2.1.0.BUILD-SNAPSHOT
- spring.data.solr
+ 5.5.0
+ 1.13.8.RELEASE
@@ -141,28 +141,9 @@
-
- org.apache.solr
- solr-langid
- ${solr}
- test
-
-
-
- org.apache.geronimo.specs
- geronimo-jcdi_2.0_spec
- 1.0.1
- test
-
-
- javax.interceptor
- javax.interceptor-api
- 1.2.1
- test
-
javax.enterprise
cdi-api
@@ -171,14 +152,8 @@
true
- javax.annotation
- javax.annotation-api
- ${javax-annotation-api}
- test
-
-
- org.apache.openwebbeans
- openwebbeans-se
+ org.apache.openwebbeans.test
+ cditest-owb
${webbeans}
test
@@ -281,22 +256,6 @@
-
- solr-next
-
-
- apache.snapshots
- Apache Snapshot Repository
- http://repository.apache.org/snapshots
-
- false
-
-
-
-
- 6.7.0-SNAPSHOT
-
-
@@ -317,8 +276,8 @@
- spring-libs-snapshot
- https://repo.spring.io/libs-snapshot
+ spring-libs-release
+ https://repo.spring.io/libs-release
diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc
index d0db4fc..3c04a0b 100644
--- a/src/main/asciidoc/preface.adoc
+++ b/src/main/asciidoc/preface.adoc
@@ -1,6 +1,6 @@
= Preface
-The Spring Data for Apache Solr project applies core Spring concepts to the development of solutions using the Apache Solr Search Engine. We provide a "template" as a high-level abstraction for storing and querying documents. You will notice similarities to the mongodb support in the Spring Framework.
+The Spring Data Solr project applies core Spring concepts to the development of solutions using the Apache Solr Search Engine. We provide a "template" as a high-level abstraction for storing and querying documents. You will notice similarities to the mongodb support in the Spring Framework.
[[project]]
[preface]
@@ -16,13 +16,13 @@ The Spring Data for Apache Solr project applies core Spring concepts to the deve
[preface]
== Requirements
-Requires Java 8 runtime and http://lucene.apache.org/solr/[Apache Solr] 6.6. Preferably the latest 6.6.x version.
+Requires http://lucene.apache.org/solr/[Apache Solr] 5. Preferably the latest 5.x version.
[source,xml]
----
org.apache.solr
- solr-solrj
+ solr-core
${solr.version}
----
\ No newline at end of file
diff --git a/src/main/asciidoc/reference/data-solr.adoc b/src/main/asciidoc/reference/data-solr.adoc
index f470f24..abfe1c0 100644
--- a/src/main/asciidoc/reference/data-solr.adoc
+++ b/src/main/asciidoc/reference/data-solr.adoc
@@ -31,7 +31,7 @@ Using the `repositories` element looks up Spring Data repositories as described
----
====
-Using the `solr-server` or `embedded-solr-server` element registers an instance of `SolrClient` in the context.
+Using the `solr-server` or `embedded-solr-server` element registers an instance of `SolrClient` in the context.
.HttpSolrClient using Namespace
====
@@ -47,7 +47,7 @@ Using the `solr-server` or `embedded-solr-server` element registers an instance
http://www.springframework.org/schema/data/solr/spring-solr.xsd">
-
+
----
====
@@ -65,7 +65,7 @@ Using the `solr-server` or `embedded-solr-server` element registers an instance
http://www.springframework.org/schema/data/solr/spring-solr.xsd">
-
+
----
====
@@ -83,7 +83,7 @@ Using the `solr-server` or `embedded-solr-server` element registers an instance
http://www.springframework.org/schema/data/solr/spring-solr.xsd">
-
+
----
====
@@ -99,13 +99,13 @@ The Spring Data Solr repositories support cannot only be activated through an XM
@Configuration
@EnableSolrRepositories
class ApplicationConfig {
-
+
@Bean
public SolrClient solrClient() {
EmbeddedSolrServerFactory factory = new EmbeddedSolrServerFactory("classpath:com/acme/solr");
return factory.getSolrServer();
}
-
+
@Bean
public SolrOperations solrTemplate() {
return new SolrTemplate(solrClient());
@@ -116,6 +116,33 @@ class ApplicationConfig {
The configuration above sets up an `EmbeddedSolrServer` which is used by the `SolrTemplate` . Spring Data Solr Repositories are activated using the `@EnableSolrRepositories` annotation, which essentially carries the same attributes as the XML namespace does. If no base package is configured, it will use the one the configuration class resides in.
+[[solr.multicore]]
+=== Multicore Support
+
+Solr handles different collections within one core. Use `MulticoreSolrClientFactory` to create separate `SolrClient` for each core.
+
+.Multicore Configuration
+====
+[source,java]
+----
+@Configuration
+@EnableSolrRepositories(multicoreSupport = true)
+class ApplicationConfig {
+
+ private static final String PROPERTY_NAME_SOLR_SERVER_URL = "solr.host";
+
+ @Resource
+ private Environment environment;
+
+ @Bean
+ public SolrClient solrClient() {
+ return new HttpSolrClient(environment.getRequiredProperty(PROPERTY_NAME_SOLR_SERVER_URL));
+ }
+
+}
+----
+====
+
[[solr.cdi]]
=== Solr Repositores using CDI
@@ -182,7 +209,7 @@ Deriving the query from the method name is not always sufficient and/or may resu
[[solr.query-methods.criterions]]
=== Query creation
-Generally the query creation mechanism for Solr works as described in <> . Here's a short example of what a Solr query method translates into:
+Generally the query creation mechanism for Solr works as described in <> . Here's a short example of what a Solr query method translates into:
.Query creation from method names
====
@@ -201,7 +228,7 @@ The method name above will be translated into the following solr query
q=name:?0 AND popularity:?1
----
-A list of supported keywords for Solr is shown below.
+A list of supported keywords for Solr is shown below.
[cols="1,2,3", options="header"]
.Supported keywords inside method names
@@ -362,12 +389,12 @@ Product.findByName=name:?0
[source,java]
----
public interface ProductRepository extends SolrCrudRepository {
-
+
List findByNamedQuery(Integer popularity);
-
+
@Query(name = "Product.findByName")
- List findByAnnotatedNamedQuery(String name);
-
+ List findByAnnotatedNamedQuery(String name);
+
}
----
@@ -388,32 +415,32 @@ Though there is already support for Entity Mapping within SolrJ, Spring Data Sol
public class Product {
@Field
private String simpleProperty;
-
+
@Field("somePropertyName")
private String namedPropery;
-
+
@Field
private List listOfValues;
-
+
@Indexed(readonly = true)
@Field("property_*")
private List ignoredFromWriting;
-
+
@Field("mappedField_*")
- private Map> mappedFieldValues;
-
+ private Map> mappedFieldValues;
+
@Dynamic
@Field("dynamicMappedField_*")
- private Map dynamicMappedFieldValues;
-
+ private Map dynamicMappedFieldValues;
+
@Field
private GeoLocation location;
-
+
}
----
====
-Taking a look as the above `MappingSolrConverter` will do as follows:
+Taking a look as the above `MappingSolrConverter` will do as follows:
[cols="1,3", options="header"]
|===
@@ -440,7 +467,7 @@ Taking a look as the above `MappingSolrConverter` will do as follows:
| `48.362893,14.534437`
|===
-To register a custom converter one must add `CustomConversions` to `SolrTemplate` initializing it with own `Converter` implementation.
+To register a custom converter one must add `CustomConversions` to `SolrTemplate` initializing it with own `Converter` implementation.
====
[source]
@@ -450,9 +477,9 @@ To register a custom converter one must add `CustomConversions` to `SolrTemplate
-
+
-
+
diff --git a/src/main/asciidoc/reference/misc.adoc b/src/main/asciidoc/reference/misc.adoc
index 89e0304..4054c94 100644
--- a/src/main/asciidoc/reference/misc.adoc
+++ b/src/main/asciidoc/reference/misc.adoc
@@ -13,7 +13,7 @@ PartialUpdates can be done using `PartialUpdate` which implements `Update`.
----
PartialUpdate update = new PartialUpdate("id", "123");
update.add("name", "updated-name");
-solrTemplate.saveBean("collection-1", update);
+solrTemplate.saveBean(update);
----
====
@@ -40,7 +40,7 @@ Faceting cannot be directly applied using the `SolrRepository` but the `SolrTemp
----
FacetQuery query = new SimpleFacetQuery(new Criteria(Criteria.WILDCARD).expression(Criteria.WILDCARD))
.setFacetOptions(new FacetOptions().addFacetOnField("name").setFacetLimit(5));
-FacetPage page = solrTemplate.queryForFacetPage("collection-1", query, Product.class);
+FacetPage page = solrTemplate.queryForFacetPage(query, Product.class);
----
====
@@ -98,7 +98,7 @@ facetOptions.setFacetMinCount(0);
Criteria criteria = new SimpleStringCriteria("*:*");
SimpleFacetQuery facetQuery = new SimpleFacetQuery(criteria).setFacetOptions(facetOptions);
-FacetPage statResultPage = solrTemplate.queryForFacetPage("collection-1", facetQuery, ExampleSolrBean.class);
+FacetPage statResultPage = solrTemplate.queryForFacetPage(facetQuery, ExampleSolrBean.class);
----
====
@@ -143,7 +143,7 @@ FacetOptions facetOptions = new FacetOptions();
facetOptions.setFacetMinCount(0);
facetOptions.addFacetOnPivot("category","dimension");
facetQuery.setFacetOptions(facetOptions);
-FacetPage facetResult = solrTemplate.queryForFacetPage("collection-1", facetQuery, Product.class);
+FacetPage facetResult = solrTemplate.queryForFacetPage(facetQuery, Product.class);
----
====
@@ -165,7 +165,7 @@ Terms Vector cannot directly be used within `SolrRepository` but can be applied
[source,java]
----
TermsQuery query = SimpleTermsQuery.queryBuilder().fields("name").build();
-TermsPage page = solrTemplate.queryForTermsPage("collection-1", query);
+TermsPage page = solrTemplate.queryForTermsPage(query);
----
====
@@ -188,7 +188,7 @@ GroupOptions groupOptions = new GroupOptions()
.addGroupByQuery(query);
groupQuery.setGroupOptions(groupOptions);
-GroupPage page = solrTemplate.queryForGroupPage("collection-1", query, Product.class);
+GroupPage page = solrTemplate.queryForGroupPage(query, Product.class);
GroupResult fieldGroup = page.getGroupResult(field);
GroupResult funcGroup = page.getGroupResult(func);
@@ -210,7 +210,7 @@ StatsOptions statsOptions = new StatsOptions().addField("price");
// query
SimpleQuery statsQuery = new SimpleQuery("*:*");
statsQuery.setStatsOptions(statsOptions);
-StatsPage statsPage = solrTemplate.queryForStatsPage("collection-1", statsQuery, Product.class);
+StatsPage statsPage = solrTemplate.queryForStatsPage(statsQuery, Product.class);
// retrieving stats info
FieldStatsResult priceStatResult = statResultPage.getFieldStatsResult("price");
@@ -245,7 +245,7 @@ StatsOptions statsOptions = new StatsOptions()
// query
SimpleQuery statsQuery = new SimpleQuery("*:*");
statsQuery.setStatsOptions(statsOptions);
-StatsPage statsPage = solrTemplate.queryForStatsPage("collection-1", statsQuery, Product.class);
+StatsPage statsPage = solrTemplate.queryForStatsPage(statsQuery, Product.class);
// field stats
FieldStatsResult categoryStatResult = statResultPage.getFieldStatsResult("category");
@@ -413,7 +413,7 @@ To highlight matches in search result add `HighlightOptions` to the `SimpleHighl
----
SimpleHighlightQuery query = new SimpleHighlightQuery(new SimpleStringCriteria("name:with"));
query.setHighlightOptions(new HighlightOptions());
-HighlightPage page = solrTemplate.queryForHighlightPage("collection-1", query, Product.class);
+HighlightPage page = solrTemplate.queryForHighlightPage(query, Product.class);
----
====
@@ -551,7 +551,7 @@ NOTE: realtime get relies on the update log feature.
====
[source,java]
----
-Optional product = solrTemplate.getById("collection-1", "123", Product.class);
+Product product = solrTemplate.getById("123", Product.class);
----
====
@@ -562,7 +562,7 @@ Multiple documents can be retrieved by providing a collection of ids as follows:
[source,java]
----
Collection ids = Arrays.asList("123", "134");
-Collection products = solrTemplate.getByIds("collection-1", ids, Product.class);
+Collection products = solrTemplate.getById(ids, Product.class);
----
====
@@ -590,60 +590,4 @@ public class MyEntity {
}
----
-====
-
-[[solr.misc.child-documents]]
-== Nested Documents
-
-Nested Documents provides the ability to add documents inside of other documents in a parent/child relationship.
-
-The nested documents need to be indexed along with the parent one and cannot be updated individually. Though nested documents will appear as individual ones in the index.
-Resolving the parent child relation is done at query query time.
-
-To indicate a property should be treated as nested object it has to be annotated with either `@o.a.s.c.solrj.beans.Field(child=true)` or `@o.s.d.s.core.mapping.ChildDocument`.
-
-====
-[source,java]
-----
-public class Book {
-
- @Id String id;
- @Indexed("type_s") String type;
- @Indexed("title_t") String title;
- @Indexed("author_s") String author;
- @Indexed("publisher_s") String publisher;
-
- @ChildDocument List reviews; <1>
-
- // setters and getters ...
-
-}
-
-public class Review {
-
- @Id String id; <2>
- @Indexed("type_s") String type;
- @Indexed("review_dt") Date date;
- @Indexed("stars_i") int stars;
- @Indexed("author_s") String author;
- @Indexed("comment_t") String comment;
-
-}
-----
-<1> Multiple child documents can be associated with a prarent one, or just use the domain type to store a single relation ship.
-<2> Note that the nested document also needs to have an unique `id` assigned.
-====
-
-Assuming `Book#type` is _book_, and `Review#type` resolves to _review_ retrieving `Book` with its child relations `reviews` can be done by altering the `fl` query parameter.
-
-====
-[source,java]
-----
-Query query = new SimpleQuery(where("id").is("theWayOfKings"));
-query.addProjectionOnField(new SimpleField("*"));
-query.addProjectionOnField(new SimpleField("[child parentFilter=type_s:book]")); <1>
-
-return solrTemplate.queryForObject("books", query, Book.class);
-----
-<1> The parent filter always defines the complete set of parent documents in the index, not the one for a single document.
====
\ No newline at end of file
diff --git a/src/main/java/org/springframework/data/solr/SolrRealtimeGetRequest.java b/src/main/java/org/springframework/data/solr/SolrRealtimeGetRequest.java
new file mode 100644
index 0000000..ada6895
--- /dev/null
+++ b/src/main/java/org/springframework/data/solr/SolrRealtimeGetRequest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014 - 2016 the original author or authors.
+ *
+ * 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 org.springframework.data.solr;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.ContentStream;
+import org.springframework.util.Assert;
+
+/**
+ * @author Christoph Strobl
+ * @since 1.4
+ * @deprecated since 2.1. Please use {@link SolrClient#getById(Collection)} instead.
+ */
+@Deprecated
+public class SolrRealtimeGetRequest extends SolrRequest {
+
+ private static final long serialVersionUID = 1500782684874146272L;
+ private Collection ids;
+
+ public SolrRealtimeGetRequest(Serializable... ids) {
+ this(Arrays.asList(ids));
+ }
+
+ public SolrRealtimeGetRequest(Collection extends Serializable> ids) {
+ super(METHOD.GET, "/get");
+
+ Assert.notEmpty(ids, "At least one 'id' is required for real time get request.");
+ Assert.noNullElements(ids.toArray(), "Real time get request can't be made for 'null' id.");
+
+ toStringIds(ids);
+ }
+
+ private void toStringIds(Collection extends Serializable> ids) {
+
+ this.ids = new ArrayList(ids.size());
+ for (Serializable id : ids) {
+ this.ids.add(id.toString());
+ }
+ }
+
+ @Override
+ public SolrParams getParams() {
+ return new ModifiableSolrParams().add("ids", this.ids.toArray(new String[this.ids.size()]));
+ }
+
+ @Override
+ public Collection getContentStreams() throws IOException {
+ return null;
+ }
+
+ @Override
+ protected QueryResponse createResponse(SolrClient client) {
+ return new QueryResponse();
+ }
+}
diff --git a/src/main/java/org/springframework/data/solr/VersionUtil.java b/src/main/java/org/springframework/data/solr/VersionUtil.java
index 1d46c5f..72fb4ae 100644
--- a/src/main/java/org/springframework/data/solr/VersionUtil.java
+++ b/src/main/java/org/springframework/data/solr/VersionUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 the original author or authors.
+ * Copyright 2012 - 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,8 @@
import org.springframework.util.ClassUtils;
/**
- * Version util uses {@link org.springframework.util.ClassUtils#isPresent(String, ClassLoader)} to determine presence of
- * certain classes that are unique to some libraries, which allows to en-/disable some of the features in eg.
+ * Version util uses {@link org.springframework.util.ClassUtils#isPresent(String)} to determine presence of certain
+ * classes that are unique to some libraries, which allows to en-/disable some of the features in eg.
* {@link org.springframework.data.solr.core.DefaultQueryParser}.
*
* @author Christoph Strobl
@@ -30,13 +30,54 @@ private VersionUtil() {
// hide utility class constructor
}
+ private static final boolean IS_SOLR_3_X_AVAILABLE = ClassUtils
+ .isPresent("org.apache.solr.client.solrj.impl.CommonsHttpSolrServer", VersionUtil.class.getClassLoader());
+
private static final boolean IS_JODATIME_AVAILABLE = ClassUtils.isPresent("org.joda.time.DateTime",
VersionUtil.class.getClassLoader());
+ private static final boolean IS_SOLR_4_2_AVAILABLE = ClassUtils.isPresent("org.apache.solr.parser.ParseException",
+ VersionUtil.class.getClassLoader());
+
+ private static final boolean IS_SOLR_4_X_AVAILABLE = ClassUtils
+ .isPresent("org.apache.solr.client.solrj.impl.CloudSolrServer", VersionUtil.class.getClassLoader());
+
+ private static final boolean IS_SOLR_5_X_AVAILABLE = ClassUtils.isPresent("org.apache.solr.client.solrj.SolrClient",
+ VersionUtil.class.getClassLoader());
+
/**
* @return true if {@code org.joda.time.DateTime} is in path
*/
public static boolean isJodaTimeAvailable() {
return IS_JODATIME_AVAILABLE;
}
+
+ /**
+ * @return true if {@link org.apache.solr.client.solrj.impl.CommonsHttpSolrServer} (removed in solr 4.0.0) is in path
+ */
+ public static boolean isSolr3XAvailable() {
+ return IS_SOLR_3_X_AVAILABLE;
+ }
+
+ /**
+ * @return true if {@link org.apache.solr.client.solrj.impl.CloudSolrServer} (introduced in solr 4.0.0) is in path
+ */
+ public static boolean isSolr4XAvailable() {
+ return IS_SOLR_4_X_AVAILABLE;
+ }
+
+ /**
+ * @return true if {@code org.apache.solr.parser.ParseException} is in path
+ */
+ public static boolean isSolr420Available() {
+ return IS_SOLR_4_2_AVAILABLE;
+ }
+
+ /**
+ * @return true if {@link org.apache.solr.client.solrj.SolrClient} (introduced in solr 5.0.0) is in path
+ */
+ public static boolean isSolr5XAvailable() {
+ return IS_SOLR_5_X_AVAILABLE;
+ }
+
}
diff --git a/src/main/java/org/springframework/data/solr/config/package-info.java b/src/main/java/org/springframework/data/solr/config/package-info.java
index 7871fdd..52f1cac 100644
--- a/src/main/java/org/springframework/data/solr/config/package-info.java
+++ b/src/main/java/org/springframework/data/solr/config/package-info.java
@@ -1,6 +1,4 @@
/**
* Spring XML namespace configuration for Solr specific repositories and SolrClient
*/
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
package org.springframework.data.solr.config;
\ No newline at end of file
diff --git a/src/main/java/org/springframework/data/solr/core/CollectionCallback.java b/src/main/java/org/springframework/data/solr/core/CollectionCallback.java
new file mode 100644
index 0000000..4833694
--- /dev/null
+++ b/src/main/java/org/springframework/data/solr/core/CollectionCallback.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 the original author or authors.
+ *
+ * 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 org.springframework.data.solr.core;
+
+import java.io.IOException;
+
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrServerException;
+
+/**
+ * Callback interface for data access code that works with {@link SolrClient}. To be used with {@link SolrOperations} to
+ * execute methods.
+ *
+ * @author Christoph Strobl
+ * @since 2.1
+ * @param
+ */
+public interface CollectionCallback {
+
+ /**
+ * @param solrClient execute
+ * @param collection the collection to operate on
+ * @return
+ * @throws SolrServerException
+ * @throws IOException
+ */
+ T doInSolr(SolrClient solrClient, String collection) throws SolrServerException, IOException;
+}
diff --git a/src/main/java/org/springframework/data/solr/core/DefaultQueryParser.java b/src/main/java/org/springframework/data/solr/core/DefaultQueryParser.java
index 6bc8ee2..2e83702 100644
--- a/src/main/java/org/springframework/data/solr/core/DefaultQueryParser.java
+++ b/src/main/java/org/springframework/data/solr/core/DefaultQueryParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 the original author or authors.
+ * Copyright 2012 - 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
@@ -28,12 +29,14 @@
import org.apache.solr.common.params.GroupParams;
import org.apache.solr.common.params.HighlightParams;
import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.SpatialParams;
import org.apache.solr.common.params.SpellingParams;
import org.apache.solr.common.params.StatsParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
+import org.springframework.data.solr.VersionUtil;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.FacetOptions;
import org.springframework.data.solr.core.query.FacetOptions.FacetParameter;
@@ -53,9 +56,9 @@
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.QueryParameter;
import org.springframework.data.solr.core.query.SolrDataQuery;
+import org.springframework.data.solr.core.query.SpatialSearchOptions;
import org.springframework.data.solr.core.query.SpellcheckOptions;
import org.springframework.data.solr.core.query.StatsOptions;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
@@ -89,7 +92,7 @@ public class DefaultQueryParser extends QueryParserBase {
public final SolrQuery doConstructSolrQuery(SolrDataQuery query) {
Assert.notNull(query, "Cannot construct solrQuery from null value.");
Assert.notNull(query.getCriteria(), "Query has to have a criteria.");
-
+
SolrQuery solrQuery = new SolrQuery();
solrQuery.setParam(CommonParams.Q, getQueryString(query));
if (query instanceof Query) {
@@ -115,29 +118,47 @@ private void processQueryOptions(SolrQuery solrQuery, Query query) {
appendDefType(solrQuery, query.getDefType());
appendRequestHandler(solrQuery, query.getRequestHandler());
appendReRankQueryHandler(solrQuery,query.getRqqValue());
-
+
processGroupOptions(solrQuery, query);
processStatsOptions(solrQuery, query);
processSpellcheckOptions(solrQuery, query);
+ processSpatialSearchOptions(solrQuery,query);
- LOGGER.info(solrQuery.toQueryString());
+ LOGGER.info("solrQuery.toQueryString() ================= "+ solrQuery.toQueryString());
+ LOGGER.info("solrQuery.toString() == ========= " + solrQuery.toString());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Constructed SolrQuery:\r\n %s", solrQuery);
}
}
+ /**
+ * @param solrQuery
+ * @param query
+ */
+ private void processSpatialSearchOptions(SolrQuery solrQuery, Query query) {
+ SpatialSearchOptions spatialOptions = query.getSpatialSearchOptions();
+ if(spatialOptions == null || StringUtils.isBlank(spatialOptions.getField()) || StringUtils.isBlank(spatialOptions.getPoint()) || StringUtils.split(spatialOptions.getPoint(), ",").length!=2) {
+ return;
+ }
+
+ solrQuery.set(SpatialParams.FIELD, spatialOptions.getField());
+ solrQuery.set(SpatialParams.DISTANCE, spatialOptions.getDistance());
+ solrQuery.set(SpatialParams.POINT, spatialOptions.getPoint());
+ }
+
/**
* @param solrQuery
* @param rqqValue
*/
private void appendReRankQueryHandler(SolrQuery solrQuery, String rqqValue) {
if(StringUtils.isNotBlank(rqqValue)) {
+ LOGGER.info("Inside appendReRankQueryHandler and rqqValue is not blank with value : " + rqqValue);
solrQuery.set("rq", "{!rerank reRankQuery=$rqq reRankDocs=1000 reRankWeight=3}");
solrQuery.set("rqq", rqqValue);
}
}
-
+
private void processFacetOptions(SolrQuery solrQuery, FacetQuery query) {
if (enableFaceting(solrQuery, query)) {
appendFacetingOnFields(solrQuery, (FacetQuery) query);
@@ -265,7 +286,7 @@ private void processSpellcheckOptions(SolrQuery solrQuery, Query query) {
SpellcheckOptions options = query.getSpellcheckOptions();
- if (options.getQuery() != null && options.getQuery().getCriteria() != null) {
+ if (options.getQuery() != null) {
solrQuery.set(SpellingParams.SPELLCHECK_Q, createQueryStringFromCriteria(options.getQuery().getCriteria()));
}
@@ -274,8 +295,9 @@ private void processSpellcheckOptions(SolrQuery solrQuery, Query query) {
for (Entry entry : options.getParams().entrySet()) {
if (entry.getValue() instanceof Iterable>) {
- for (Object o : ((Iterable>) entry.getValue())) {
- params.add(entry.getKey(), o.toString());
+ Iterator> it = ((Iterable>) entry.getValue()).iterator();
+ while (it.hasNext()) {
+ params.add(entry.getKey(), it.next().toString());
}
} else if (ObjectUtils.isArray(entry.getValue())) {
for (Object o : ObjectUtils.toObjectArray(entry.getValue())) {
@@ -357,8 +379,8 @@ private boolean enableFaceting(SolrQuery solrQuery, FacetQuery query) {
solrQuery.setFacetMinCount(facetOptions.getFacetMinCount());
solrQuery.setFacetLimit(facetOptions.getPageable().getPageSize());
if (facetOptions.getPageable().getPageNumber() > 0) {
- long offset = Math.max(0, facetOptions.getPageable().getOffset());
- solrQuery.set(FacetParams.FACET_OFFSET, "" + offset);
+ int offset = Math.max(0, facetOptions.getPageable().getOffset());
+ solrQuery.set(FacetParams.FACET_OFFSET, offset);
}
if (FacetOptions.FacetSort.INDEX.equals(facetOptions.getFacetSort())) {
solrQuery.setFacetSort(FacetParams.FACET_SORT_INDEX);
@@ -447,6 +469,10 @@ private void appendFacetingQueries(SolrQuery solrQuery, FacetQuery query) {
}
private void appendFacetingOnPivot(SolrQuery solrQuery, FacetQuery query) {
+ if (VersionUtil.isSolr3XAvailable()) {
+ throw new UnsupportedOperationException(
+ "Pivot Facets are not available for solr version lower than 4.x - Please check your depdendencies.");
+ }
FacetOptions facetOptions = query.getFacetOptions();
String[] pivotFields = convertFieldListToStringArray(facetOptions.getFacetOnPivots());
@@ -476,7 +502,7 @@ protected void appendFilterQuery(SolrQuery solrQuery, List filterQu
* @param solrQuery
* @param sort
*/
- protected void appendSort(SolrQuery solrQuery, @Nullable Sort sort) {
+ protected void appendSort(SolrQuery solrQuery, Sort sort) {
if (sort == null) {
return;
}
@@ -501,7 +527,7 @@ private String[] convertStringListToArray(List listOfString) {
}
private List getFilterQueryStrings(List filterQueries) {
- List filterQueryStrings = new ArrayList<>(filterQueries.size());
+ List filterQueryStrings = new ArrayList(filterQueries.size());
for (FilterQuery filterQuery : filterQueries) {
String filterQueryString = getQueryString(filterQuery);
diff --git a/src/main/java/org/springframework/data/solr/core/QueryParser.java b/src/main/java/org/springframework/data/solr/core/QueryParser.java
index e96896e..3fe9356 100644
--- a/src/main/java/org/springframework/data/solr/core/QueryParser.java
+++ b/src/main/java/org/springframework/data/solr/core/QueryParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 the original author or authors.
+ * Copyright 2012 - 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,14 +27,14 @@
* Will be parsed to a SolrQuery that outputs the following
* q=field_1%3Avalue_1+AND+field_2%3Avalue_2*&fl=field_3&start=0&rows=10
*
- *
+ *
* @author Christoph Strobl
*/
public interface QueryParser {
/**
* Convert given Query into a SolrQuery executable via {@link SolrClient}
- *
+ *
* @param query
* @return
*/
@@ -42,7 +42,7 @@ public interface QueryParser {
/**
* Get the queryString to use withSolrQuery.setParam(CommonParams.Q, "queryString"}
- *
+ *
* @param query
* @return String representation of query without faceting, pagination, projection...
*/
@@ -50,7 +50,7 @@ public interface QueryParser {
/**
* Register an additional converter for transforming object values to solr readable format
- *
+ *
* @param converter
*/
void registerConverter(Converter, ?> converter);
diff --git a/src/main/java/org/springframework/data/solr/core/QueryParserBase.java b/src/main/java/org/springframework/data/solr/core/QueryParserBase.java
index bb0adeb..2e013d5 100644
--- a/src/main/java/org/springframework/data/solr/core/QueryParserBase.java
+++ b/src/main/java/org/springframework/data/solr/core/QueryParserBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 the original author or authors.
+ * Copyright 2012 - 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,8 @@
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.SpatialParams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.geo.Box;
@@ -54,7 +56,6 @@
import org.springframework.data.solr.core.query.Query.Operator;
import org.springframework.data.solr.core.query.QueryStringHolder;
import org.springframework.data.solr.core.query.SolrDataQuery;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -73,9 +74,11 @@ public abstract class QueryParserBase implement
protected static final String DELIMINATOR = ":";
protected static final String NOT = "-";
protected static final String BOOST = "^";
+
+ private final Logger log = LoggerFactory.getLogger(QueryParserBase.class);
protected final GenericConversionService conversionService = new GenericConversionService();
- private final List critieraEntryProcessors = new ArrayList<>();
+ private final List critieraEntryProcessors = new ArrayList();
private final PredicateProcessor defaultProcessor = new DefaultProcessor();
{
@@ -111,12 +114,30 @@ public abstract class QueryParserBase implement
@Override
public String getQueryString(SolrDataQuery query) {
+ log.info("query.toString()" + query.toString());
if (query.getCriteria() == null) {
return null;
}
-
+ log.info("query.getCriteria() ============" + query.getCriteria().toString());
String queryString = createQueryStringFromNode(query.getCriteria());
+ if(queryString != null && queryString.indexOf("rqq")>-1)
+ queryString = queryString.substring(0,queryString.indexOf("rqq"));
+ log.info("===========queryString==========" + queryString);
queryString = prependJoin(queryString, query);
+ log.info("------------queryString-------------" + queryString);
+ return queryString;
+ }
+
+ public String getRqqValue(SolrDataQuery query) {
+ log.info("query.toString()" + query.toString());
+ if (query.getCriteria() == null) {
+ return null;
+ }
+ log.info("query.getCriteria() ============" + query.getCriteria().toString());
+ String queryString = createQueryStringFromNode(query.getCriteria());
+ int indexOfRqq = queryString.indexOf("rqq");
+ if(queryString != null && indexOfRqq > -1 && indexOfRqq+4 < queryString.length())
+ queryString = queryString.substring(indexOfRqq+4);
return queryString;
}
@@ -181,6 +202,7 @@ protected String createQueryStringFromCriteria(Criteria criteria) {
/**
* Creates query string representation of a single critiera
*
+ * @param criteria
* @return
*/
protected String createQueryFragmentForCriteria(Criteria part) {
@@ -222,13 +244,13 @@ protected String createQueryFragmentForCriteria(Criteria part) {
queryFragment.append(")");
}
if (!Float.isNaN(criteria.getBoost())) {
- queryFragment.append(BOOST).append(criteria.getBoost());
+ queryFragment.append(BOOST + criteria.getBoost());
}
return queryFragment.toString();
}
- private String getNullsafeFieldName(@Nullable Field field) {
+ private String getNullsafeFieldName(Field field) {
if (field == null || field.getName() == null) {
return "";
}
@@ -265,7 +287,7 @@ protected String createFunctionFragment(Function function, int level) {
sb.append(function.getOperation());
sb.append('(');
if (function.hasArguments()) {
- List solrReadableArguments = new ArrayList<>();
+ List solrReadableArguments = new ArrayList();
for (Object arg : function.getArguments()) {
Assert.notNull(arg, "Unable to parse 'null' within function arguments.");
if (arg instanceof Function) {
@@ -295,7 +317,7 @@ protected String createFunctionFragment(Function function, int level) {
* @param query
* @return
*/
- protected String prependJoin(String queryString, @Nullable SolrDataQuery query) {
+ protected String prependJoin(String queryString, SolrDataQuery query) {
if (query == null || query.getJoin() == null) {
return queryString;
}
@@ -312,12 +334,12 @@ protected String prependJoin(String queryString, @Nullable SolrDataQuery query)
* @param offset
* @param rows
*/
- protected void appendPagination(SolrQuery query, @Nullable Long offset, @Nullable Integer rows) {
+ protected void appendPagination(SolrQuery query, Integer offset, Integer rows) {
if (offset != null && offset.intValue() >= 0) {
- query.setStart(offset.intValue());
+ query.setStart(offset);
}
- if (rows != null && rows >= 0) {
+ if (rows != null && rows.intValue() >= 0) {
query.setRows(rows);
}
}
@@ -332,7 +354,7 @@ protected void appendProjectionOnFields(SolrQuery solrQuery, List fields)
if (CollectionUtils.isEmpty(fields)) {
return;
}
- List solrReadableFields = new ArrayList<>();
+ List solrReadableFields = new ArrayList();
for (Field field : fields) {
if (field instanceof CalculatedField) {
solrReadableFields.add(createCalculatedFieldFragment((CalculatedField) field));
@@ -349,7 +371,7 @@ protected void appendProjectionOnFields(SolrQuery solrQuery, List fields)
* @param solrQuery
* @param defaultOperator
*/
- protected void appendDefaultOperator(SolrQuery solrQuery, @Nullable Operator defaultOperator) {
+ protected void appendDefaultOperator(SolrQuery solrQuery, Operator defaultOperator) {
if (defaultOperator != null && !Query.Operator.NONE.equals(defaultOperator)) {
solrQuery.set("q.op", defaultOperator.asQueryStringRepresentation());
}
@@ -361,7 +383,7 @@ protected void appendDefaultOperator(SolrQuery solrQuery, @Nullable Operator def
* @param solrQuery
* @param timeAllowed
*/
- protected void appendTimeAllowed(SolrQuery solrQuery, @Nullable Integer timeAllowed) {
+ protected void appendTimeAllowed(SolrQuery solrQuery, Integer timeAllowed) {
if (timeAllowed != null) {
solrQuery.setTimeAllowed(timeAllowed);
}
@@ -373,7 +395,7 @@ protected void appendTimeAllowed(SolrQuery solrQuery, @Nullable Integer timeAllo
* @param solrQuery
* @param defType
*/
- protected void appendDefType(SolrQuery solrQuery, @Nullable String defType) {
+ protected void appendDefType(SolrQuery solrQuery, String defType) {
if (StringUtils.isNotBlank(defType)) {
solrQuery.set("defType", defType);
}
@@ -385,7 +407,7 @@ protected void appendDefType(SolrQuery solrQuery, @Nullable String defType) {
* @param solrQuery
* @param requestHandler
*/
- protected void appendRequestHandler(SolrQuery solrQuery, @Nullable String requestHandler) {
+ protected void appendRequestHandler(SolrQuery solrQuery, String requestHandler) {
if (StringUtils.isNotBlank(requestHandler)) {
solrQuery.add(CommonParams.QT, requestHandler);
}
@@ -421,7 +443,7 @@ public interface PredicateProcessor {
* @param predicate
* @return true if predicate can be processed by this parser
*/
- boolean canProcess(@Nullable Predicate predicate);
+ boolean canProcess(Predicate predicate);
/**
* Create query string representation of given {@link Predicate}
@@ -430,7 +452,7 @@ public interface PredicateProcessor {
* @param field
* @return
*/
- Object process(@Nullable Predicate predicate, @Nullable Field field);
+ Object process(Predicate predicate, Field field);
}
@@ -450,7 +472,6 @@ class CriteriaQueryStringValueProvider implements Iterator {
}
@SuppressWarnings("unchecked")
- @Nullable
private T getPredicateValue(Predicate predicate) {
PredicateProcessor processor = findMatchingProcessor(predicate);
return (T) processor.process(predicate, criteria.getField());
@@ -474,7 +495,8 @@ public boolean hasNext() {
@Override
public String next() {
Object o = getPredicateValue(this.delegate.next());
- return o != null ? o.toString() : null;
+ String s = o != null ? o.toString() : null;
+ return s;
}
@Override
@@ -500,7 +522,7 @@ abstract class BasePredicateProcessor implements PredicateProcessor {
"\\(", "\\)", "\\{", "\\}", "\\[", "\\]", "\\^", "\\~", "\\*", "\\?", "\\:", "\\\\" };
@Override
- public Object process(@Nullable Predicate predicate, @Nullable Field field) {
+ public Object process(Predicate predicate, Field field) {
if (predicate == null || predicate.getValue() == null) {
return null;
}
@@ -529,8 +551,7 @@ private String processWhiteSpaces(String criteriaValue) {
return criteriaValue;
}
- @Nullable
- protected abstract Object doProcess(@Nullable Predicate predicate, Field field);
+ protected abstract Object doProcess(Predicate predicate, Field field);
}
@@ -542,15 +563,12 @@ private String processWhiteSpaces(String criteriaValue) {
class DefaultProcessor extends BasePredicateProcessor {
@Override
- public boolean canProcess(@Nullable Predicate predicate) {
+ public boolean canProcess(Predicate predicate) {
return true;
}
@Override
- public Object doProcess(@Nullable Predicate predicate, Field field) {
-
- Assert.notNull(predicate, "Predicate must not be null!");
-
+ public Object doProcess(Predicate predicate, Field field) {
return filterCriteriaValue(predicate.getValue());
}
@@ -564,14 +582,12 @@ public Object doProcess(@Nullable Predicate predicate, Field field) {
class ExpressionProcessor extends BasePredicateProcessor {
@Override
- public boolean canProcess(@Nullable Predicate predicate) {
- return predicate != null && OperationKey.EXPRESSION.getKey().equals(predicate.getKey());
+ public boolean canProcess(Predicate predicate) {
+ return OperationKey.EXPRESSION.getKey().equals(predicate.getKey());
}
@Override
- public Object doProcess(@Nullable Predicate predicate, Field field) {
- Assert.notNull(predicate, "Predicate must not be null!");
-
+ public Object doProcess(Predicate predicate, Field field) {
return predicate.getValue().toString();
}
@@ -587,20 +603,20 @@ class BetweenProcessor extends BasePredicateProcessor {
private static final String RANGE_OPERATOR = " TO ";
@Override
- public boolean canProcess(@Nullable Predicate predicate) {
- return predicate != null && OperationKey.BETWEEN.getKey().equals(predicate.getKey());
+ public boolean canProcess(Predicate predicate) {
+ return OperationKey.BETWEEN.getKey().equals(predicate.getKey());
}
@Override
- public Object doProcess(@Nullable Predicate predicate, Field field) {
+ public Object doProcess(Predicate predicate, Field field) {
Object[] args = (Object[]) predicate.getValue();
- String rangeFragment = (Boolean) args[2] ? "[" : "{";
+ String rangeFragment = ((Boolean) args[2]).booleanValue() ? "[" : "{";
rangeFragment += createRangeFragment(args[0], args[1]);
- rangeFragment += (Boolean) args[3] ? "]" : "}";
+ rangeFragment += ((Boolean) args[3]).booleanValue() ? "]" : "}";
return rangeFragment;
}
- protected String createRangeFragment(@Nullable Object rangeStart, @Nullable Object rangeEnd) {
+ protected String createRangeFragment(Object rangeStart, Object rangeEnd) {
String rangeFragment = "";
rangeFragment += (rangeStart != null ? filterCriteriaValue(rangeStart) : Criteria.WILDCARD);
rangeFragment += RANGE_OPERATOR;
@@ -618,15 +634,12 @@ protected String createRangeFragment(@Nullable Object rangeStart, @Nullable Obje
class NearProcessor extends BetweenProcessor {
@Override
- public boolean canProcess(@Nullable Predicate predicate) {
- return predicate != null && OperationKey.NEAR.getKey().equals(predicate.getKey());
+ public boolean canProcess(Predicate predicate) {
+ return OperationKey.NEAR.getKey().equals(predicate.getKey());
}
@Override
- public Object doProcess(@Nullable Predicate predicate, Field field) {
-
- Assert.notNull(predicate, "Predicate must not be null!");
-
+ public Object doProcess(Predicate predicate, Field field) {
String nearFragment;
Object[] args = (Object[]) predicate.getValue();
if (args[0] instanceof Box) {
@@ -641,7 +654,7 @@ public Object doProcess(@Nullable Predicate predicate, Field field) {
return nearFragment;
}
- protected String createSpatialFunctionFragment(@Nullable String fieldName, org.springframework.data.geo.Point location,
+ protected String createSpatialFunctionFragment(String fieldName, org.springframework.data.geo.Point location,
Distance distance, String function) {
String spatialFragment = "{!" + function + " " + SpatialParams.POINT + "=";
spatialFragment += filterCriteriaValue(location);
@@ -661,16 +674,12 @@ protected String createSpatialFunctionFragment(@Nullable String fieldName, org.s
class WithinProcessor extends NearProcessor {
@Override
- public boolean canProcess(@Nullable Predicate predicate) {
+ public boolean canProcess(Predicate predicate) {
return OperationKey.WITHIN.getKey().equals(predicate.getKey());
}
- @Nullable
@Override
- public Object doProcess(@Nullable Predicate predicate, Field field) {
-
- Assert.notNull(predicate, "Predicate must not be null!");
-
+ public Object doProcess(Predicate predicate, Field field) {
Object[] args = (Object[]) predicate.getValue();
return createSpatialFunctionFragment(field.getName(), (org.springframework.data.geo.Point) args[0],
(Distance) args[1], "geofilt");
@@ -686,16 +695,12 @@ public Object doProcess(@Nullable Predicate predicate, Field field) {
class FuzzyProcessor extends BasePredicateProcessor {
@Override
- public boolean canProcess(@Nullable Predicate predicate) {
- return predicate != null && OperationKey.FUZZY.getKey().equals(predicate.getKey());
+ public boolean canProcess(Predicate predicate) {
+ return OperationKey.FUZZY.getKey().equals(predicate.getKey());
}
- @Nullable
@Override
- protected Object doProcess(@Nullable Predicate predicate, Field field) {
-
- Assert.notNull(predicate, "Predicate must not be null!");
-
+ protected Object doProcess(Predicate predicate, Field field) {
Object[] args = (Object[]) predicate.getValue();
Float distance = (Float) args[1];
return filterCriteriaValue(args[0]) + "~" + (distance.isNaN() ? "" : distance);
@@ -711,16 +716,12 @@ protected Object doProcess(@Nullable Predicate predicate, Field field) {
class SloppyProcessor extends BasePredicateProcessor {
@Override
- public boolean canProcess(@Nullable Predicate predicate) {
- return predicate != null && OperationKey.SLOPPY.getKey().equals(predicate.getKey());
+ public boolean canProcess(Predicate predicate) {
+ return OperationKey.SLOPPY.getKey().equals(predicate.getKey());
}
- @Nullable
@Override
- protected Object doProcess(@Nullable Predicate predicate, Field field) {
-
- Assert.notNull(predicate, "Predicate must not be null!");
-
+ protected Object doProcess(Predicate predicate, Field field) {
Object[] args = (Object[]) predicate.getValue();
Integer distance = (Integer) args[1];
return filterCriteriaValue(args[0]) + "~" + distance;
@@ -737,17 +738,14 @@ protected Object doProcess(@Nullable Predicate predicate, Field field) {
class WildcardProcessor extends BasePredicateProcessor {
@Override
- public boolean canProcess(@Nullable Predicate predicate) {
- return predicate != null && (OperationKey.CONTAINS.getKey().equals(predicate.getKey())
+ public boolean canProcess(Predicate predicate) {
+ return OperationKey.CONTAINS.getKey().equals(predicate.getKey())
|| OperationKey.STARTS_WITH.getKey().equals(predicate.getKey())
- || OperationKey.ENDS_WITH.getKey().equals(predicate.getKey()));
+ || OperationKey.ENDS_WITH.getKey().equals(predicate.getKey());
}
@Override
- protected Object doProcess(@Nullable Predicate predicate, Field field) {
-
- Assert.notNull(predicate, "Predicate must not be null!");
-
+ protected Object doProcess(Predicate predicate, Field field) {
Object filteredValue = filterCriteriaValue(predicate.getValue());
if (OperationKey.CONTAINS.getKey().equals(predicate.getKey())) {
return Criteria.WILDCARD + filteredValue + Criteria.WILDCARD;
@@ -768,22 +766,18 @@ protected Object doProcess(@Nullable Predicate predicate, Field field) {
class FunctionProcessor extends BasePredicateProcessor {
@Override
- public boolean canProcess(@Nullable Predicate predicate) {
- return predicate != null && OperationKey.FUNCTION.getKey().equals(predicate.getKey());
+ public boolean canProcess(Predicate predicate) {
+ return OperationKey.FUNCTION.getKey().equals(predicate.getKey());
}
@Override
- @Nullable
- protected Object doProcess(@Nullable Predicate predicate, Field field) {
-
- Assert.notNull(predicate, "Predicate must not be null!");
-
+ protected Object doProcess(Predicate predicate, Field field) {
return createFunctionFragment((Function) predicate.getValue(), 0);
}
}
- private static void setObjectName(Map namesAssociation, Object object, String name) {
+ private static final void setObjectName(Map namesAssociation, Object object, String name) {
namesAssociation.put(name, object);
}
@@ -805,7 +799,7 @@ interface NamedObjects {
*/
static class NamedObjectsQuery extends AbstractQueryDecorator implements NamedObjects {
- private Map namesAssociation = new HashMap<>();
+ private Map namesAssociation = new HashMap();
public NamedObjectsQuery(Query query) {
super(query);
@@ -830,7 +824,7 @@ public Map getNamesAssociation() {
*/
static class NamedObjectsFacetQuery extends AbstractFacetQueryDecorator implements NamedObjects {
- private Map namesAssociation = new HashMap<>();
+ private Map namesAssociation = new HashMap();
public NamedObjectsFacetQuery(FacetQuery query) {
super(query);
@@ -854,7 +848,7 @@ public Map getNamesAssociation() {
*/
static class NamedObjectsHighlightQuery extends AbstractHighlightQueryDecorator implements NamedObjects {
- private Map namesAssociation = new HashMap<>();
+ private Map namesAssociation = new HashMap();
public NamedObjectsHighlightQuery(HighlightQuery query) {
super(query);
@@ -879,7 +873,7 @@ public Map getNamesAssociation() {
static class NamedObjectsFacetAndHighlightQuery extends AbstractFacetAndHighlightQueryDecorator
implements NamedObjects {
- private Map namesAssociation = new HashMap<>();
+ private Map namesAssociation = new HashMap();
public NamedObjectsFacetAndHighlightQuery(FacetAndHighlightQuery query) {
super(query);
diff --git a/src/main/java/org/springframework/data/solr/core/QueryParsers.java b/src/main/java/org/springframework/data/solr/core/QueryParsers.java
index 0d7d192..7addf83 100644
--- a/src/main/java/org/springframework/data/solr/core/QueryParsers.java
+++ b/src/main/java/org/springframework/data/solr/core/QueryParsers.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 the original author or authors.
+ * Copyright 2012 - 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
import org.springframework.data.solr.core.query.HighlightQuery;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SolrDataQuery;
+import org.springframework.data.solr.core.query.SuggestQuery;
import org.springframework.data.solr.core.query.TermsQuery;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -38,11 +39,11 @@ public class QueryParsers {
private final List parserPairs;
- private final Map, QueryParser> cache = new LinkedHashMap<>();
+ private final Map, QueryParser> cache = new LinkedHashMap, QueryParser>();
public QueryParsers() {
- this.parserPairs = new ArrayList<>(4);
-
+ this.parserPairs = new ArrayList(5);
+ parserPairs.add(new QueryParserPair(SuggestQuery.class, new SuggestQueryParser()));
parserPairs.add(new QueryParserPair(TermsQuery.class, new TermsQueryParser()));
parserPairs.add(new QueryParserPair(FacetQuery.class, DEFAULT_QUERY_PARSER));
parserPairs.add(new QueryParserPair(HighlightQuery.class, DEFAULT_QUERY_PARSER));
@@ -86,6 +87,7 @@ public void registerParser(Class extends SolrDataQuery> clazz, QueryParser par
* QueryParserPair holds reference form the {@link SolrQuery} to the {@link QueryParser} suitable for it
*
* @author Christoph Strobl
+ *
*/
private static class QueryParserPair {
@@ -106,6 +108,7 @@ public QueryParser getParser() {
}
/**
+ *
* @param clazz
* @return true if {@link ClassUtils#isAssignable(Class, Class)}
*/
diff --git a/src/main/java/org/springframework/data/solr/core/RequestMethod.java b/src/main/java/org/springframework/data/solr/core/RequestMethod.java
index 0e6e62d..b5b4395 100644
--- a/src/main/java/org/springframework/data/solr/core/RequestMethod.java
+++ b/src/main/java/org/springframework/data/solr/core/RequestMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-2017 the original author or authors.
+ * Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,6 @@
*/
public enum RequestMethod {
- GET, POST, PUT
+ GET, POST, PUT;
}
diff --git a/src/main/java/org/springframework/data/solr/core/ResultHelper.java b/src/main/java/org/springframework/data/solr/core/ResultHelper.java
index 631fced..d9b33b1 100644
--- a/src/main/java/org/springframework/data/solr/core/ResultHelper.java
+++ b/src/main/java/org/springframework/data/solr/core/ResultHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 the original author or authors.
+ * Copyright 2012 - 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,8 @@
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.RangeFacet;
import org.apache.solr.client.solrj.response.SpellCheckResponse;
+import org.apache.solr.client.solrj.response.SuggesterResponse;
+import org.apache.solr.client.solrj.response.Suggestion;
import org.apache.solr.client.solrj.response.TermsResponse;
import org.apache.solr.client.solrj.response.TermsResponse.Term;
import org.apache.solr.common.SolrDocumentList;
@@ -44,16 +46,36 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
-import org.springframework.data.mapping.MappingException;
+import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.repository.util.ClassUtils;
+import org.springframework.data.solr.VersionUtil;
import org.springframework.data.solr.core.query.FacetQuery;
import org.springframework.data.solr.core.query.Field;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleField;
import org.springframework.data.solr.core.query.SimplePivotField;
-import org.springframework.data.solr.core.query.result.*;
+import org.springframework.data.solr.core.query.result.FacetFieldEntry;
+import org.springframework.data.solr.core.query.result.FacetPivotFieldEntry;
+import org.springframework.data.solr.core.query.result.FacetQueryEntry;
+import org.springframework.data.solr.core.query.result.FieldStatsResult;
+import org.springframework.data.solr.core.query.result.GroupEntry;
+import org.springframework.data.solr.core.query.result.GroupResult;
+import org.springframework.data.solr.core.query.result.HighlightEntry;
+import org.springframework.data.solr.core.query.result.SimpleFacetFieldEntry;
+import org.springframework.data.solr.core.query.result.SimpleFacetPivotEntry;
+import org.springframework.data.solr.core.query.result.SimpleFacetQueryEntry;
+import org.springframework.data.solr.core.query.result.SimpleFieldStatsResult;
+import org.springframework.data.solr.core.query.result.SimpleGroupEntry;
+import org.springframework.data.solr.core.query.result.SimpleGroupResult;
+import org.springframework.data.solr.core.query.result.SimpleStatsResult;
+import org.springframework.data.solr.core.query.result.SimpleSuggestDictionaryEntry;
+import org.springframework.data.solr.core.query.result.SimpleTermsFieldEntry;
+import org.springframework.data.solr.core.query.result.SolrResultPage;
import org.springframework.data.solr.core.query.result.SpellcheckQueryResult.Alternative;
-import org.springframework.lang.Nullable;
+import org.springframework.data.solr.core.query.result.SpellcheckQueryResult.Collations;
+import org.springframework.data.solr.core.query.result.StatsResult;
+import org.springframework.data.solr.core.query.result.SuggestDictionaryEntry;
+import org.springframework.data.solr.core.query.result.TermsFieldEntry;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
@@ -61,7 +83,7 @@
/**
* Use Result Helper to extract various parameters from the QueryResponse and convert it into a proper Format taking
* care of non existent and null elements with the response.
- *
+ *
* @author Christoph Strobl
* @author Francisco Spaeth
* @author Venil Noronha
@@ -70,16 +92,42 @@ final class ResultHelper {
private ResultHelper() {}
- static Map> convertTermsQueryResponseToTermsMap(@Nullable QueryResponse response) {
+
+ static Map> convertSuggesterQueryResponseToSuggesterMap(QueryResponse response) {
+ if (response == null || response.getSuggesterResponse() == null || response.getSuggesterResponse().getSuggestions() == null) {
+ return Collections.emptyMap();
+ }
+
+ SuggesterResponse suggesterResponse = response.getSuggesterResponse();
+ Map> result = new LinkedHashMap>(
+ suggesterResponse.getSuggestions().size());
+
+ for (Map.Entry> entry : suggesterResponse.getSuggestions().entrySet()) {
+ List terms = new ArrayList(entry.getValue().size());
+ for (Suggestion term : entry.getValue()) {
+ SimpleSuggestDictionaryEntry suggestionEntry = new SimpleSuggestDictionaryEntry(term.getTerm(), term.getWeight());
+ suggestionEntry.setDictionary(entry.getKey());
+ suggestionEntry.setPayLoad(term.getPayload());
+ terms.add(suggestionEntry);
+ }
+ result.put(entry.getKey(), terms);
+ }
+
+ return result;
+ }
+
+
+ static Map> convertTermsQueryResponseToTermsMap(QueryResponse response) {
if (response == null || response.getTermsResponse() == null || response.getTermsResponse().getTermMap() == null) {
return Collections.emptyMap();
}
TermsResponse termsResponse = response.getTermsResponse();
- Map> result = new LinkedHashMap<>(termsResponse.getTermMap().size());
+ Map> result = new LinkedHashMap>(
+ termsResponse.getTermMap().size());
for (Map.Entry> entry : termsResponse.getTermMap().entrySet()) {
- List terms = new ArrayList<>(entry.getValue().size());
+ List terms = new ArrayList(entry.getValue().size());
for (Term term : entry.getValue()) {
SimpleTermsFieldEntry termsEntry = new SimpleTermsFieldEntry(term.getTerm(), term.getFrequency());
termsEntry.setField(entry.getKey());
@@ -98,7 +146,7 @@ static Map> convertFacetQueryResponseToFacetPageMap
if (!hasFacets(query, response)) {
return Collections.emptyMap();
}
- Map> facetResult = new LinkedHashMap<>();
+ Map> facetResult = new LinkedHashMap>();
if (!CollectionUtils.isEmpty(response.getFacetFields())) {
int initalPageSize = Math.max(1, query.getFacetOptions().getPageable().getPageSize());
@@ -106,16 +154,16 @@ static Map> convertFacetQueryResponseToFacetPageMap
if (facetField != null && StringUtils.hasText(facetField.getName())) {
Field field = new SimpleField(facetField.getName());
if (!CollectionUtils.isEmpty(facetField.getValues())) {
- List pageEntries = new ArrayList<>(initalPageSize);
+ List pageEntries = new ArrayList(initalPageSize);
for (Count count : facetField.getValues()) {
if (count != null) {
pageEntries.add(new SimpleFacetFieldEntry(field, count.getName(), count.getCount()));
}
}
- facetResult.put(field, new SolrResultPage<>(pageEntries, query.getFacetOptions().getPageable(),
- facetField.getValueCount(), null));
+ facetResult.put(field, new SolrResultPage(pageEntries,
+ query.getFacetOptions().getPageable(), facetField.getValueCount(), null));
} else {
- facetResult.put(field, new SolrResultPage<>(Collections. emptyList(),
+ facetResult.put(field, new SolrResultPage(Collections. emptyList(),
query.getFacetOptions().getPageable(), 0, null));
}
}
@@ -127,7 +175,12 @@ static Map> convertFacetQueryResponseToFacetPageMap
static Map> convertFacetQueryResponseToFacetPivotMap(
FacetQuery query, QueryResponse response) {
- Map> facetResult = new LinkedHashMap<>();
+ if (VersionUtil.isSolr3XAvailable()) {
+ // pivot facets are a solr 4+ Feature
+ return Collections.emptyMap();
+ }
+
+ Map> facetResult = new LinkedHashMap>();
NamedList> facetPivot = response.getFacetPivot();
if (facetPivot != null && facetPivot.size() > 0) {
for (int i = 0; i < facetPivot.size(); i++) {
@@ -145,7 +198,7 @@ private static List convertPivotResult(List pi
return Collections.emptyList();
}
- ArrayList pivotFieldEntries = new ArrayList<>();
+ ArrayList pivotFieldEntries = new ArrayList();
for (PivotField pivotField : pivotResult) {
SimpleFacetPivotEntry pivotFieldEntry = new SimpleFacetPivotEntry(new SimpleField(pivotField.getField()),
@@ -175,7 +228,7 @@ static Map> convertFacetQueryResponseToRangeFacetPa
if (!hasFacets(query, response) || CollectionUtils.isEmpty(response.getFacetRanges())) {
return Collections.emptyMap();
}
- Map> facetResult = new LinkedHashMap<>();
+ Map> facetResult = new LinkedHashMap>();
Pageable pageable = query.getFacetOptions().getPageable();
int initalPageSize = pageable.getPageSize();
@@ -190,7 +243,7 @@ static Map> convertFacetQueryResponseToRangeFacetPa
List entries;
long total;
if (!CollectionUtils.isEmpty(rangeFacet.getCounts())) {
- entries = new ArrayList<>(initalPageSize);
+ entries = new ArrayList(initalPageSize);
for (RangeFacet.Count count : rangeFacet.getCounts()) {
entries.add(new SimpleFacetFieldEntry(field, count.getValue(), count.getCount()));
}
@@ -200,7 +253,7 @@ static Map> convertFacetQueryResponseToRangeFacetPa
total = 0;
}
- facetResult.put(field, new SolrResultPage<>(entries, pageable, total, null));
+ facetResult.put(field, new SolrResultPage(entries, pageable, total, null));
}
@@ -214,7 +267,7 @@ static List convertFacetQueryResponseToFacetQueryResult(FacetQu
return Collections.emptyList();
}
- List facetResult = new ArrayList<>();
+ List facetResult = new ArrayList();
if (!CollectionUtils.isEmpty(response.getFacetQuery())) {
for (Entry entry : response.getFacetQuery().entrySet()) {
@@ -224,13 +277,13 @@ static List convertFacetQueryResponseToFacetQueryResult(FacetQu
return facetResult;
}
- static List> convertAndAddHighlightQueryResponseToResultPage(@Nullable QueryResponse response,
- @Nullable SolrResultPage page) {
+ static List> convertAndAddHighlightQueryResponseToResultPage(QueryResponse response,
+ SolrResultPage page) {
if (response == null || CollectionUtils.isEmpty(response.getHighlighting()) || page == null) {
return Collections.emptyList();
}
- List> mappedHighlights = new ArrayList<>(page.getSize());
+ List> mappedHighlights = new ArrayList>(page.getSize());
Map>> highlighting = response.getHighlighting();
for (T item : page) {
@@ -243,7 +296,7 @@ static List> convertAndAddHighlightQueryResponseToResultPa
private static HighlightEntry processHighlightingForPageEntry(
Map>> highlighting, T pageEntry) {
- HighlightEntry highlightEntry = new HighlightEntry<>(pageEntry);
+ HighlightEntry highlightEntry = new HighlightEntry(pageEntry);
Object itemId = getMappedId(pageEntry);
Map> highlights = highlighting.get(itemId.toString());
@@ -269,7 +322,9 @@ private static Object getMappedId(Object o) {
if (annotation != null) {
try {
return FieldUtils.readField(field, o, true);
- } catch (IllegalArgumentException | IllegalAccessException e) {
+ } catch (IllegalArgumentException e) {
+ throw new MappingException("Id property could not be accessed!", e);
+ } catch (IllegalAccessException e) {
throw new MappingException("Id property could not be accessed!", e);
}
}
@@ -290,19 +345,19 @@ static Map