Value slice is not a member of play.api.libs.iteratee.Enumerator

I am writing code based on "Asynchronous Iterators for Large Recordsets" described at https://github.com/websudos/phantom#partial-select-queries

import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat import org.joda.time.format.DateTimeFormatter import com.anomaly42.aml.dao.CassandraConnector import com.websudos.phantom.CassandraTable import com.websudos.phantom.Implicits._ object People extends People { def getPersonByUpdatedAt(from:String, to:String, start: Int, limit: Int) = { val dtf:DateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ"); val fromDateTime = dtf.parseDateTime(from) val toDateTime = dtf.parseDateTime(to) People.select(_.updated_at, _.firstName).allowFiltering.where(_.updated_at gte fromDateTime).and(_.updated_at lte toDateTime).fetchEnumerator().slice(start, limit).collect } } 

I use the following library dependency:

 scalaVersion := "2.11.6" libraryDependencies ++= Seq( "com.websudos" %% "phantom-dsl" % "1.5.4", many more... ) 

But during compilation, I get the following error:

 value slice is not a member of play.api.libs.iteratee.Enumerator[(org.joda.time.DateTime, Option[String])] 

What I'm trying to do is write a query that returns the next "limit" number of results, starting with "start", the getPersonByUpdatedAt () method is called each time.

+5
source share
2 answers

There are quite a few implementation details. First of all, if you are after pagination, there may be an easier way to achieve this with simple range queries, rather than filtered data.

Look at using CLUSTERING ORDER that calling ALLOW FILTERING should not be there. Also, without CLUSTERING ORDER by default, the Martmur3 block is not ordered by default, so you have no guarantee of receiving the data in the same order that you wrote it.

Most likely your pagination will not work at all. Last but not least, using counters directly is probably not what you need.

They are asynchronous, so you need to map inside the future to get the fragment, but aside, enumerations are useful when something like Spark loads the entire table at once, for example, a lot of results.

To summarize all this, inside the people table:

 object id extends UUIDColumn(this) with PartitionKey[UUID]// doesn't have to be UUID object start extends DateTimeColumn(this) with ClusteringOrder[DateTime] with Ascending object end extends DateTimeColumn(this) with ClusteringOrder[DateTime] with Ascending 

And just use fetch() and then Seq.slice from the Scala collection library. The above assumes that you want to paginate in ascending order, for example, first gets the oldest.

You also need to figure out what a realistic partition key might be. If 2 users are updated at the same time, in the worst case, you lose data and end the FIFO queue, for example, the last update is currently “winning”. I used id above, but this is not what you need, obviously.

And you may need several tables in which you store people so that you can cover all the queries that you need.

+3
source

You must use Iteratee and Enumerator from Play. In your case, you need to:

 import com.websudos.phantom.iteratee.Iteratee val enumerator = People.select(_.updated_at, _.firstName).allowFiltering.where(_.updated_at gte fromDateTime).and(_.updated_at lte toDateTime).fetchEnumerator val iteratee = Iteratee.slice[PeopleCaseClass](start, limit) enumerator.run( iteratee ).map( _.foldLeft( List.empty[PeopleCaseClass] )( (l,e) => { e :: l } )) 

Hope this helps

+1
source

Source: https://habr.com/ru/post/1215066/


All Articles