Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Update slashem custom score script support. #42

Merged
merged 11 commits into from
Commits on Jun 1, 2012
  1. @holdenk
Commits on Jun 3, 2012
  1. @epishkin @holdenk

    Fixed several typos

    epishkin authored holdenk committed
  2. @adamalix @holdenk

    initial stuff

    adamalix authored holdenk committed
  3. @holdenk
  4. @adamalix @holdenk

    Custom score script support tests.

    adamalix authored holdenk committed
  5. @adamalix @holdenk

    Refactor scoring functions for elastic.

    adamalix authored holdenk committed
  6. @holdenk
  7. @holdenk

    Bump version #

    holdenk authored
  8. @holdenk
  9. @holdenk
  10. @holdenk

    Merge remote-tracking branch '4sq/master'

    holdenk authored
    Conflicts:
    	src/main/scala/com/foursquare/slashem/QueryBuilder.scala
    	src/test/scala/com/foursquare/slashem/ElasticQueryTest.scala
This page is out of date. Refresh to see the latest.
View
2  build.sbt
@@ -1,6 +1,6 @@
name := "slashem"
-version := "0.11.1"
+version := "0.12.1"
organization := "com.foursquare"
View
6 src/main/scala/com/foursquare/slashem/QueryBuilder.scala
@@ -337,16 +337,16 @@ case class QueryBuilder[M <: Record[M], Ord, Lim, MM <: MinimumMatchType, Y, H <
}
/** Boost a specific field/query. WARNING: NOT TYPE SAFE NO VALIDATION ETC. */
- def boostField(s: String): QueryBuilder[M, Ord, Lim, MM, Y, H, Q, MinFacetCount, FacetLimit, ST] = {
+ def boostField(s: String): QueryBuilder[M, Ord, Lim, MM, Y, H, Q, MinFacetCount, FacetLimit, ScoreScript] = {
this.copy(boostFields=WeightedField(s,1)::boostFields)
}
/** Boost a field (type safe version) */
- def boostField[F](f: M => SlashemField[F,M], boost: Double = 1): QueryBuilder[M, Ord, Lim, MM, Y, H, Q, MinFacetCount, FacetLimit, ST] = {
+ def boostField[F](f: M => SlashemField[F,M], boost: Double = 1): QueryBuilder[M, Ord, Lim, MM, Y, H, Q, MinFacetCount, FacetLimit, ScoreScript] = {
this.copy(boostFields=WeightedField(f(meta).name,boost)::boostFields)
}
/** Handle a more complex field boost */
- def scoreBoostField(f: M => ScoreBoost): QueryBuilder[M, Ord, Lim, MM, Y, H, Q, MinFacetCount, FacetLimit, ST] = {
+ def scoreBoostField(f: M => ScoreBoost): QueryBuilder[M, Ord, Lim, MM, Y, H, Q, MinFacetCount, FacetLimit, ScoreScript] = {
this.copy(boostFields=f(meta)::boostFields)
}
View
35 src/test/scala/com/foursquare/slashem/ElasticQueryTest.scala
@@ -367,7 +367,7 @@ class ElasticQueryTest extends SpecsMatchers with ScalaCheckMatchers {
def testObjectIdListFieldEmptyNin {
val response1 = ESimplePanda where (_.favvenueids nin List()) fetch()
Assert.assertEquals(response1.response.results.length, 8)
- }
+ }
@Test
def testListFieldNin {
@@ -413,13 +413,39 @@ class ElasticQueryTest extends SpecsMatchers with ScalaCheckMatchers {
Assert.assertEquals(response1.response.results.length, 2)
}
+ def testFilters {
+ // grab 2 results, filter to 1
+ val res1 = ESimplePanda where (_.hugenums contains 1L) filter(_.nicknamesString in List("jerry")) fetch()
+ Assert.assertEquals(res1.response.results.length, 1)
+ }
+
+
@Before
def hoboPrepIndex() {
ESimplePanda.meta.node = ElasticNode.node
ESimpleGeoPanda.meta.node = ElasticNode.node
- val plugin = new FourSquareScorePlugin()
-
+ //Setup the mapping for the regular index
val client = ESimplePanda.meta.client
+ try {
+ val indexReq = Requests.createIndexRequest(ESimplePanda.meta.indexName)
+ client.admin.indices().create(indexReq).actionGet()
+ client.admin().indices().prepareRefresh().execute().actionGet()
+ val indexName = ESimplePanda.meta.indexName
+ val mapping = """
+ { "slashemdoc" :{
+ "properties" : {
+ "nicknamesString" : { type: "string", store: "no", analyzer:"whitespace"}
+ }
+ }}"""
+ val mappingReq = Requests.putMappingRequest(ESimplePanda.meta.indexName).source(mapping).`type`("slashemdoc")
+ val mappingResponse = client.admin().indices().putMapping(mappingReq).actionGet()
+ } catch {
+ case e => {
+ e.printStackTrace();
+ println("Error creating the regular index, may allready exist ("+e+")")
+ }
+ }
+ val plugin = new FourSquareScorePlugin()
//Set up the geo panda index
val geoClient = ESimpleGeoPanda.meta.client
@@ -478,6 +504,7 @@ class ElasticQueryTest extends SpecsMatchers with ScalaCheckMatchers {
.field("id","4c809f4251ada1cdc3790b10")
.field("favnums", favnums1)
.field("nicknames", nicknames1)
+ .field("nicknamesString", nicknames1.asScala.mkString(" "))
.field("hugenums", hugenums1)
.field("termsfield", terms1)
.field("favvenueids", venueids1)
@@ -493,6 +520,7 @@ class ElasticQueryTest extends SpecsMatchers with ScalaCheckMatchers {
.field("foreign","pants")
.field("favnums", favnums2)
.field("nicknames", nicknames2)
+ .field("nicknamesString", nicknames2.asScala.mkString(" "))
.field("hugenums", hugenums2)
.endObject()
).execute()
@@ -507,6 +535,7 @@ class ElasticQueryTest extends SpecsMatchers with ScalaCheckMatchers {
.field("foreign","pants")
.field("favnums", favnums3)
.field("nicknames", nicknames3)
+ .field("nicknamesString", nicknames3.asScala.mkString(" "))
.field("hugenums", hugenums3)
.endObject()
).execute()
View
2  src/test/scala/com/foursquare/slashem/ElasticTest.scala
@@ -4,6 +4,7 @@ object ESimplePanda extends ESimplePanda with ElasticMeta[ESimplePanda] {
//Force local for testing
override val useTransport = false
override val clusterName = "simpletest" //Override me knthx
+ override val indexName = "esimplepanda"
}
class ESimplePanda extends ElasticSchema[ESimplePanda] {
def meta = ESimplePanda
@@ -17,6 +18,7 @@ class ESimplePanda extends ElasticSchema[ESimplePanda] {
object foreign extends SlashemStringField(this)
object favnums extends SlashemIntListField(this)
object nicknames extends SlashemStringListField(this)
+ object nicknamesString extends SlashemStringField(this)
object hugenums extends SlashemLongListField(this)
object termsfield extends SlashemUnanalyzedStringField(this)
object favvenueids extends SlashemObjectIdListField(this)
View
75 src/test/scala/com/foursquare/slashem/QueryTest.scala
@@ -736,80 +736,5 @@ class QueryTest extends SpecsMatchers with ScalaCheckMatchers {
Assert.assertEquals(Nil, (expected.toSet &~ qp.toSet).toList)
}
- @Test
- def thingsThatShouldntCompile {
- val compiler = new Compiler
- def check(code: String, shouldTypeCheck: Boolean = false): Unit = {
- compiler.typeCheck(code) aka "'%s' compiles!".format(code) must_== shouldTypeCheck
- }
-
- //Make sure our basic does compile
- check("""SVenueTest where (_.metall any) useQueryType("edismax") orderDesc(_.decayedPopularity1)""", shouldTypeCheck = true)
- //Make sure trying to limit a limit query doesn't work
- check("""SVenueTest where (_.metall any) useQueryType("edismax") orderDesc(_.decayedPopularity1) limit(1) limit(10)""")
- //Conflicting order statements
- check("""SVenueTest where (_.metall any) useQueryType("edismax") orderDesc(_.decayedPopularity1) orderDesc(_.meta_categories) """)
- check("""SEventTest where (_.default contains "hixxy") useQueryType("edismax") filter(_.tags inRadius(geoLat, geoLong, 1))""")
- check("""
- import org.joda.time.{DateTime, DateTimeZone}
- val d1 = new DateTime(2011, 5, 1, 0, 0, 0, 0, DateTimeZone.UTC)
- val d2 = new DateTime(2011, 5, 2, 0, 0, 0, 0, DateTimeZone.UTC)
- SEventTest where (_.name inRange(d1, d2))""")
-
-
-
- check("""
- case class TestPirate(state: Option[String])
- SVenueTest where (_.name eqs "test") selectCase(_.name,((x: Option[String]) => TestPirate(x)))
- """,shouldTypeCheck=true)
- check("""
- case class TestPirate(state: Option[String])
- SVenueTest where (_.name eqs "test") selectCase(_.name,((x: Option[String]) => TestPirate(x))) selectCase(_.name,((x: Option[String]) => TestPirate(x)))
- """,shouldTypeCheck=false)
-
- }
-
- //Stolen from Rogue
- class Compiler {
- import java.io.{PrintWriter, Writer}
- import scala.io.Source
- import scala.tools.nsc.{Interpreter, InterpreterResults, Settings}
-
- class NullWriter extends Writer {
- override def close() = ()
- override def flush() = ()
- override def write(arr: Array[Char], x: Int, y: Int): Unit = ()
- }
-
- private val settings = new Settings
- val loader = manifest[SVenueTest].erasure.getClassLoader
- settings.classpath.value = Source.fromURL(loader.getResource("app.class.path")).mkString
- settings.bootclasspath.append(Source.fromURL(loader.getResource("boot.class.path")).mkString)
- settings.deprecation.value = true // enable detailed deprecation warnings
- settings.unchecked.value = true // enable detailed unchecked warnings
-
- // This is deprecated in 2.9.x, but we need to use it for compatibility with 2.8.x
- private val interpreter =
- new Interpreter(
- settings,
- /*
- * It's a good idea to comment out this second parameter when adding or modifying
- * tests that shouldn't compile, to make sure that the tests don't compile for the
- * right reason.
- *
- */
- new PrintWriter(new NullWriter())
- )
-
- interpreter.interpret("""import com.foursquare.slashem._""")
-
- def typeCheck(code: String): Boolean = {
- interpreter.interpret(code) match {
- case InterpreterResults.Success => true
- case InterpreterResults.Error => false
- case InterpreterResults.Incomplete => throw new Exception("Incomplete code snippet")
- }
- }
- }
}
View
108 src/test/scala/com/foursquare/slashem/TypeCheckTests.scala
@@ -0,0 +1,108 @@
+package com.foursquare.slashem
+
+import com.foursquare.slashem._
+
+import org.bson.types.ObjectId
+import org.junit.Test
+import org.junit._
+
+import org.scalacheck._
+import org.scalacheck.Gen._
+import org.scalacheck.Arbitrary.arbitrary
+
+import org.specs.SpecsMatchers
+import org.specs.matcher.ScalaCheckMatchers
+
+
+class TypeCheckTests extends SpecsMatchers with ScalaCheckMatchers {
+ @Test
+ def thingsThatShouldntCompile {
+ val compiler = new Compiler
+ def check(code: String, shouldTypeCheck: Boolean = false): Unit = {
+ compiler.typeCheck(code) aka "'%s' compiles!".format(code) must_== shouldTypeCheck
+ }
+
+ //Make sure our basic does compile
+ check("""SVenueTest where (_.metall any) useQueryType("edismax") orderDesc(_.decayedPopularity1)""", shouldTypeCheck = true)
+ //Make sure trying to limit a limit query doesn't work
+ check("""SVenueTest where (_.metall any) useQueryType("edismax") orderDesc(_.decayedPopularity1) limit(1) limit(10)""")
+ //Conflicting order statements
+ check("""SVenueTest where (_.metall any) useQueryType("edismax") orderDesc(_.decayedPopularity1) orderDesc(_.meta_categories) """)
+ check("""SEventTest where (_.default contains "hixxy") useQueryType("edismax") filter(_.tags inRadius(geoLat, geoLong, 1))""")
+ check("""
+ import org.joda.time.{DateTime, DateTimeZone}
+ val d1 = new DateTime(2011, 5, 1, 0, 0, 0, 0, DateTimeZone.UTC)
+ val d2 = new DateTime(2011, 5, 2, 0, 0, 0, 0, DateTimeZone.UTC)
+ SEventTest where (_.name inRange(d1, d2))""")
+
+
+
+ check("""
+ case class TestPirate(state: Option[String])
+ SVenueTest where (_.name eqs "test") selectCase(_.name,((x: Option[String]) => TestPirate(x)))
+ """,shouldTypeCheck=true)
+ check("""
+ case class TestPirate(state: Option[String])
+ SVenueTest where (_.name eqs "test") selectCase(_.name,((x: Option[String]) => TestPirate(x))) selectCase(_.name,((x: Option[String]) => TestPirate(x)))
+ """,shouldTypeCheck=false)
+
+ check("""
+ val params: Map[String, Any] = Map("lat" -> -31.1, "lon" -> 74.0, "weight" -> 2000, "weight2" -> 0.03)
+ ESimpleGeoPanda where (_.name eqs "test") scoreBoostField(_.point recipSqeGeoDistance(40, -74, 1, 5000, 1))
+ """,shouldTypeCheck=true)
+
+ check("""
+ val params: Map[String, Any] = Map("lat" -> -31.1, "lon" -> 74.0, "weight" -> 2000, "weight2" -> 0.03)
+ ESimpleGeoPanda where (_.name eqs "test") customScore("distance_score_magic", params)
+ """,shouldTypeCheck=true)
+
+ check("""
+ val params: Map[String, Any] = Map("lat" -> -31.1, "lon" -> 74.0, "weight" -> 2000, "weight2" -> 0.03)
+ ESimpleGeoPanda where (_.name eqs "test") scoreBoostField(_.point recipSqeGeoDistance(40, -74, 1, 5000, 1)) customScore("distance_score_magic", params)
+ """,shouldTypeCheck=false)
+ }
+
+ //Stolen from Rogue
+ class Compiler {
+ import java.io.{PrintWriter, Writer}
+ import scala.io.Source
+ import scala.tools.nsc.{Interpreter, InterpreterResults, Settings}
+
+ class NullWriter extends Writer {
+ override def close() = ()
+ override def flush() = ()
+ override def write(arr: Array[Char], x: Int, y: Int): Unit = ()
+ }
+
+ private val settings = new Settings
+ val loader = manifest[SVenueTest].erasure.getClassLoader
+ settings.classpath.value = Source.fromURL(loader.getResource("app.class.path")).mkString
+ settings.bootclasspath.append(Source.fromURL(loader.getResource("boot.class.path")).mkString)
+ settings.deprecation.value = true // enable detailed deprecation warnings
+ settings.unchecked.value = true // enable detailed unchecked warnings
+
+ // This is deprecated in 2.9.x, but we need to use it for compatibility with 2.8.x
+ private val interpreter =
+ new Interpreter(
+ settings,
+ /*
+ * It's a good idea to comment out this second parameter when adding or modifying
+ * tests that shouldn't compile, to make sure that the tests don't compile for the
+ * right reason.
+ *
+ */
+ new PrintWriter(new NullWriter())
+ )
+
+ interpreter.interpret("""import com.foursquare.slashem._""")
+
+ def typeCheck(code: String): Boolean = {
+ interpreter.interpret(code) match {
+ case InterpreterResults.Success => true
+ case InterpreterResults.Error => false
+ case InterpreterResults.Incomplete => throw new Exception("Incomplete code snippet")
+ }
+ }
+ }
+
+}
Something went wrong with that request. Please try again.