Skip to content

Commit

Permalink
Merge pull request #78 from algolia/feat/search
Browse files Browse the repository at this point in the history
Add complete search options
  • Loading branch information
ElPicador committed Feb 18, 2016
2 parents 8ed0810 + 1de9eca commit 5c5ff18
Show file tree
Hide file tree
Showing 34 changed files with 744 additions and 182 deletions.
32 changes: 23 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,32 +130,40 @@ val indexing2: Future[Indexing] = client.execute {
You can now search for contacts using firstname, lastname, company, etc. (even with typos):
```scala
// search by firstname
client.execute { search into "contacts" query "jimmie" }
client.execute { search into "contacts" query Query(query = Some("jimmie")) }

// search a firstname with typo
client.execute { search into "contacts" query "jimie" }
client.execute { search into "contacts" query Query(query = Some("jimie")) }

// search for a company
client.execute { search into "contacts" query "california paint" }
client.execute { search into "contacts" query Query(query = Some("california paint")) }

// search for a firstname & company
client.execute { search into "contacts" query "jimmie paint" }
client.execute { search into "contacts" query Query(query = Some("jimmie paint")) }
```

Settings can be customized to tune the search behavior. For example, you can add a custom sort by number of followers to the already great built-in relevance:
```scala
//Not yet implemented
client.execute {
changeSettings of "myIndex" `with` IndexSettings(
customRanking = Some(Seq(CustomRanking.desc("followers")))
)
}
```

You can also configure the list of attributes you want to index by order of importance (first = most important):
```scala
//Not yet implemented
client.execute {
changeSettings of "myIndex" `with` IndexSettings(
attributesToIndex = Some(Seq("lastname", "firstname", "company"))
)
}
```

Since the engine is designed to suggest results as you type, you'll generally search by prefix. In this case the order of attributes is very important to decide which hit is the best:
```scala
client.execute { search into "contacts" query "or" }
client.execute { search into "contacts" query "jim" }
client.execute { search into "contacts" query Query(query = Some("or")) }
client.execute { search into "contacts" query Query(query = Some("jim")) }
```


Expand Down Expand Up @@ -540,7 +548,13 @@ The list of keywords is:
* **distinct**: If set to 1, enables the distinct feature, disabled by default, if the `attributeForDistinct` index setting is set. This feature is similar to the SQL "distinct" keyword. When enabled in a query with the `distinct=1` parameter, all hits containing a duplicate value for the attributeForDistinct attribute are removed from results. For example, if the chosen attribute is `show_name` and several hits have the same value for `show_name`, then only the best one is kept and the others are removed.

```scala
//Not yet implemented
client.execute {
search into "myIndex" query Query(
query = Some("query string"),
attributesToRetrieve = Some(Seq("firstname", "lastname")),
hitsPerPage = Some(50)
)
}
```

The server response will look like:
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/algolia/AlgoliaDsl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
package algolia

import algolia.definitions._
import algolia.objects._
import algolia.responses._
import org.json4s.CustomSerializer
import org.json4s.JsonAST.JString
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/algolia/definitions/ApiKeyDefinition.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
package algolia.definitions

import algolia.http._
import algolia.responses.{AllKeys, ApiKey, CreateUpdateKey, DeleteKey}
import algolia.objects.ApiKey
import algolia.responses.{AllKeys, CreateUpdateKey, DeleteKey}
import algolia.{AlgoliaClient, Executable}
import org.json4s.Formats
import org.json4s.native.Serialization._
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/algolia/definitions/GetObjectDefinition.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ package algolia.definitions

import algolia.http.HttpPayload
import algolia.inputs.{Request, Requests}
import algolia.responses.{Get, Results}
import algolia.responses.{GetObject, Results}
import algolia.{AlgoliaClient, Executable, _}
import org.json4s.Formats
import org.json4s.JsonAST.JObject
Expand Down Expand Up @@ -79,10 +79,10 @@ trait GetObjectDsl {

}

implicit object GetObjectDefinitionExecutable extends Executable[GetObjectDefinition, Get] {
implicit object GetObjectDefinitionExecutable extends Executable[GetObjectDefinition, GetObject] {

override def apply(client: AlgoliaClient, query: GetObjectDefinition)(implicit executor: ExecutionContext): Future[Get] = {
(client request[JObject] query.build()).map(Get(_))
override def apply(client: AlgoliaClient, query: GetObjectDefinition)(implicit executor: ExecutionContext): Future[GetObject] = {
(client request[JObject] query.build()).map(GetObject(_))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
package algolia.definitions

import algolia.http.{GET, HttpPayload, PUT}
import algolia.responses.{IndexSettings, Task}
import algolia.objects.IndexSettings
import algolia.responses.Task
import algolia.{AlgoliaClient, Executable}
import org.json4s.Formats
import org.json4s.native.Serialization._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ package algolia.definitions

import algolia.http.{HttpPayload, POST}
import algolia.inputs.PartialUpdateObject
import algolia.responses.{ApiKey, Task}
import algolia.objects.ApiKey
import algolia.responses.Task
import algolia.{AlgoliaClient, Executable}
import org.json4s.Formats
import org.json4s.native.Serialization.write
Expand Down
35 changes: 16 additions & 19 deletions src/main/scala/algolia/definitions/SearchDefinition.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,28 @@
package algolia.definitions

import algolia._
import algolia.http.HttpPayload
import algolia.responses.Search
import algolia.http.{POST, HttpPayload}
import algolia.objects.Query
import algolia.responses.SearchResult
import org.json4s.Formats
import org.json4s.native.Serialization.write

import scala.concurrent.{ExecutionContext, Future}

case class SearchDefinition(index: String,
query: Option[String] = None,
hitsPerPage: Option[Int] = None)(implicit val formats: Formats) extends Definition {
query: Option[Query] = None)(implicit val formats: Formats) extends Definition {

def into(index: String): SearchDefinition = this

def hitsPerPage(h: Int): SearchDefinition = copy(hitsPerPage = Some(h))

def query(q: String): SearchDefinition = copy(query = Some(q))
def query(q: Query): SearchDefinition = copy(query = Some(q))

override private[algolia] def build(): HttpPayload = {
val params = Seq() ++
query.map(q => s"query=$q") ++
hitsPerPage.map(h => s"hitsPerPage=$h")

val body = Map("params" -> params.mkString("&"))

HttpPayload(http.GET, Seq("1", "indexes", index, "query"), body = Some(write(body)))
val body = Map("params" -> query.map(_.toParam))

HttpPayload(
POST,
Seq("1", "indexes", index, "query"),
body = Some(write(body)),
isSearch = true
)
}
}

Expand All @@ -63,9 +60,9 @@ trait SearchDsl {

}

implicit object SearchDefinitionExecutable extends Executable[SearchDefinition, Search] {
override def apply(client: AlgoliaClient, query: SearchDefinition)(implicit executor: ExecutionContext): Future[Search] = {
client request[Search] query.build()
implicit object SearchDefinitionExecutable extends Executable[SearchDefinition, SearchResult] {
override def apply(client: AlgoliaClient, query: SearchDefinition)(implicit executor: ExecutionContext): Future[SearchResult] = {
client request[SearchResult] query.build()
}
}

Expand Down
48 changes: 48 additions & 0 deletions src/main/scala/algolia/objects/Acl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2016 Algolia
* http://www.algolia.com/
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package algolia.objects

sealed trait Acl

object Acl {

case object search extends Acl

case object browse extends Acl

case object addObject extends Acl

case object deleteObject extends Acl

case object deleteIndex extends Acl

case object settings extends Acl

case object editSettings extends Acl

case object analytics extends Acl

case object listIndexes extends Acl

}
26 changes: 26 additions & 0 deletions src/main/scala/algolia/objects/AltCorrection.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2016 Algolia
* http://www.algolia.com/
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package algolia.objects

case class AltCorrection(word: String, correction: String, nbTypos: Int)
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* THE SOFTWARE.
*/

package algolia.responses
package algolia.objects

case class ApiKey(validity: Option[Int] = None,
maxQueriesPerIPPerHour: Option[Int] = None,
Expand All @@ -31,27 +31,3 @@ case class ApiKey(validity: Option[Int] = None,
referers: Option[Seq[String]] = None,
queryParameters: Option[String] = None,
description: Option[String] = None)

sealed trait Acl

object Acl {

case object search extends Acl

case object browse extends Acl

case object addObject extends Acl

case object deleteObject extends Acl

case object deleteIndex extends Acl

case object settings extends Acl

case object editSettings extends Acl

case object analytics extends Acl

case object listIndexes extends Acl

}
30 changes: 30 additions & 0 deletions src/main/scala/algolia/objects/AroundLatLng.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2016 Algolia
* http://www.algolia.com/
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package algolia.objects

case class AroundLatLng(lat: String, lng: String) {

override def toString = s"$lat,$lng"

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,16 @@
* THE SOFTWARE.
*/

package algolia.dsl
package algolia.objects

import algolia.AlgoliaDsl._
import algolia.AlgoliaTest
sealed trait AttributesToIndex

class QueryTest extends AlgoliaTest {
object AttributesToIndex {

case class Nothing()
case class unordered(attribute: String) extends AttributesToIndex

describe("query") {
case class attribute(attribute: String) extends AttributesToIndex

it("should search simple query") {
search into "index" query "toto"
}

it("should search a query with options") {
search into "index" query "toto" hitsPerPage 1
}

}
case class attributes(attributes: String*) extends AttributesToIndex

}
34 changes: 34 additions & 0 deletions src/main/scala/algolia/objects/CustomRanking.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2016 Algolia
* http://www.algolia.com/
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package algolia.objects

sealed trait CustomRanking

object CustomRanking {

case class asc(attribute: String) extends CustomRanking

case class desc(attribute: String) extends CustomRanking

}
Loading

0 comments on commit 5c5ff18

Please sign in to comment.