diff --git a/bin/schema.xml b/bin/schema.xml
index 0cf0bc7..4267f4c 100644
--- a/bin/schema.xml
+++ b/bin/schema.xml
@@ -10,6 +10,9 @@
+
+
+
id
diff --git a/solrHttp.go b/solrHttp.go
index 24cff89..75df470 100644
--- a/solrHttp.go
+++ b/solrHttp.go
@@ -35,6 +35,9 @@ type solrHttp struct {
router Router
}
+// M is a shortcut for map[string]interface{}
+type M map[string]interface{}
+
func NewSolrHTTP(useHTTPS bool, collection string, options ...func(*solrHttp)) (SolrHTTP, error) {
solrCli := solrHttp{collection: collection, minRf: 1, insecureSkipVerify: false, readTimeoutSeconds: 20, writeTimeoutSeconds: 30, connectTimeoutSeconds: 5}
logger := log.New(os.Stdout, "[SolrClient] ", log.LstdFlags)
@@ -303,6 +306,16 @@ func Cursor(c string) func(url.Values) {
}
}
+// JSONFacet helper function for defining JSON Facets.
+func JSONFacet(opts M) func(url.Values) {
+ jsonFacet, err := json.Marshal(opts)
+ return func(p url.Values) {
+ if err == nil {
+ p["json.facet"] = []string{string(jsonFacet)}
+ }
+ }
+}
+
func UrlVals(urlVals url.Values) func(url.Values) {
return func(p url.Values) {
for key := range urlVals {
diff --git a/solrResponse.go b/solrResponse.go
index ccacc94..5f74cc8 100644
--- a/solrResponse.go
+++ b/solrResponse.go
@@ -8,9 +8,10 @@ type SolrResponse struct {
Indent string `json:"indent"`
Wt string `json:"wt"`
} `json:"params"`
- Response Response `json:"response"`
- NextCursorMark string `json:"nextCursorMark"`
- Adds Adds `json:"adds"`
+ Response Response `json:"response"`
+ NextCursorMark string `json:"nextCursorMark"`
+ Adds Adds `json:"adds"`
+ Facets map[string]interface{} `json:"facets"`
}
type Response struct {
diff --git a/solr_query_test.go b/solr_query_test.go
new file mode 100644
index 0000000..2ba41c9
--- /dev/null
+++ b/solr_query_test.go
@@ -0,0 +1,89 @@
+package solr_test
+
+import (
+ "net/url"
+ "time"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "github.com/sendgrid/go-solr"
+)
+
+var _ = Describe("Solr Client", func() {
+ var solrClient solr.SolrZK
+ var solrHttp solr.SolrHTTP
+ var solrHttpRetrier solr.SolrHTTP
+ var locator solr.SolrLocator
+ solrClient = solr.NewSolrZK("zk:2181", "solr", "solrtest")
+ locator = solrClient.GetSolrLocator()
+ const limit int = 100
+ uuid, _ := newUUID()
+ shardKey := "mycrazysha" + uuid
+
+ err := solrClient.Listen()
+ BeforeEach(func() {
+ Expect(err).To(BeNil())
+ https, _ := solrClient.UseHTTPS()
+ solrHttp, err = solr.NewSolrHTTP(https, "solrtest", solr.User("solr"), solr.Password("admin"), solr.MinRF(2))
+ Expect(err).To(BeNil())
+ solrHttpRetrier = solr.NewSolrHttpRetrier(solrHttp, 5, 100*time.Millisecond)
+
+ var salaries = []float32{40000, 60000, 80000, 100000, 120000}
+ var firstNames = []string{"john", "jane", "alice", "bob", "ashley", "gordon", "peter", "cindy", "brie", "alex"}
+ for i := 0; i < limit; i++ {
+ iterationId, _ := newUUID()
+ lastId := shardKey + "!rando" + iterationId
+ doc := map[string]interface{}{
+ "id": lastId,
+ "email": "rando" + iterationId + "@sendgrid.com",
+ "first_name": firstNames[i%len(firstNames)],
+ "last_name": uuid,
+ "salary": salaries[i%len(salaries)],
+ }
+ leader, err := locator.GetLeaders(doc["id"].(string))
+ Expect(err).To(BeNil())
+
+ if i < limit-1 {
+ err := solrHttp.Update(leader, true, doc, solr.Commit(false))
+ Expect(err).To(BeNil())
+ } else {
+ err := solrHttp.Update(leader, true, doc, solr.Commit(true))
+ Expect(err).To(BeNil())
+ }
+ }
+ })
+
+ AfterEach(func() {
+ replicas, err := locator.GetReplicasFromRoute(shardKey + "!")
+ Expect(err).To(BeNil())
+ err = solrHttp.Update(replicas, false, nil, solr.Commit(true), solr.DeleteStreamBody("last_name:*"))
+ Expect(err).To(BeNil())
+ })
+
+ Describe("Test Faceting", func() {
+ It("can return facets", func() {
+ replicas, err := locator.GetReplicaUris()
+ Expect(err).To(BeNil())
+
+ query := []func(url.Values){
+ solr.Query("*:*"),
+ solr.JSONFacet(
+ solr.M{
+ "max_salary": "max(salary)",
+ "salary": solr.M{
+ "type": "terms",
+ "field": "salary",
+ },
+ },
+ ),
+ }
+
+ r, err := solrHttp.Select(replicas, query...)
+ Expect(err).To(BeNil())
+ Expect(r).To(Not(BeNil()))
+ Expect(r.Response.NumFound).To(BeEquivalentTo(limit))
+ Expect(r.Facets["max_salary"].(float64)).To(BeEquivalentTo(120000))
+ Expect(len(r.Facets["salary"].(map[string]interface{})["buckets"].([]interface{}))).To(BeEquivalentTo(5))
+ })
+ })
+})