2015-03-10 27 views
5

Ben https://github.com/websudos/phantom#partial-select-queriesdeğer dilim play.api.libs.iteratee.Enumerator

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 
    } 
} 
Ben kütüphane bağımlılık aşağıdaki kullanıyorum

de açıklanan "büyük rekor setleri için zaman uyumsuz yineleyiciler" dayalı kod yazıyorum üyesi değildir:

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

Ben çalışıyorum neyim: derleme yaparken

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

Ama hata aşağıdaki almak yapılacak g 'başlangıç', getPersonByUpdatedAt() metodu olarak adlandırılan her zaman başlayarak sonraki sonuçlar da limit sayıda geri getiren bir sorgu yazmaya.

cevap

3

burada ele almak epeyce uygulama ayrıntı bulunmaktadır. Her şeyden önce, sayfalamadan sonraysanız, filtrelenmiş veriler yerine basit aralıklı sorgularla bunu elde etmenin daha kolay bir yolu olabilir.

CLUSTERING ORDER'u kullanarak, ALLOW FILTERING numaralı telefonu arayabilmeniz için bir göz atın. Dahası, CLUSTERING ORDER olmadan varsayılan Murmur3 bölümleyici aslında sipariş, bu yüzden bunu yazdım aynı sırada veri alma garantisi var değildir. olasılıkla sayfalandırma gerçekten hiç işe gitmiyor demektir

. Son olarak, enumeratorları doğrudan kullanmak muhtemelen sizin peşinde olduğunuz şey değildir.

Eşzamansızdırlar, bu nedenle bir dilim elde etmek için bir geleceğin haritasını eşleştirmeniz gerekir, ancak bir kenara, Spark gibi bir şey bir kerede tüm tabloyu yüklediğinde, örneğin çok sayıda sonuç olduğunda, numaralandırıcılar yararlıdır.

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 

Ve sadece Scala koleksiyonları kütüphaneden fetch() ve sonra Seq.slice kullanın:

kişi Tablonun içinde hepsini Özetle. Yukarıdaki, artan düzende sıralamak istediğinizi varsayar, örneğin en eski olanı alır.

Ayrıca, gerçekçi bir bölüm anahtarının ne olabileceğini bulmanız da gerekir. 2 kullanıcı aynı anda güncellenir ise en kötü durum belirli bir zaman "kazanır" de örneğin son güncellemeden, verileri kaybedersiniz ve bir FIFO kuyruğuna ile rüzgar olduğunu. Yukarıda id kullandım, ama açıkça ihtiyacınız olan şey bu değil.

Ayrıca, ihtiyaç duyduğunuz tüm sorguları kapsayabilmek için insanları depoladığınız birkaç tabloya sahip olmanız gerekebilir.

+0

Merhaba @flavian yardımcı olacaktır, Cevabınız için teşekkür. Veritabanımın milyonlarca kaydı var ve bu yüzden bunu Enumerators kullanarak uygulamak zorunda kalacağım. Tarih sütununu, sizin tarafınızdan belirtildiği gibi 'KÜME SİPARİŞİ 'ile tanımladım, ancak" İHTİYAÇ FİLTRELEME "yi kullanmazsam, çalışma zamanı hataları alıyorum. Aşağıdaki ifadeyle derleme hatasından kurtulmayı başardım: People.select (_. Updated_at, _.firstName) .allowFiltering.where (_. Updated_at gte fromDateTime) .ve (_. Updated_at lte toDateTime) .setFetchSize (pageSize) .fetchEnumerator() Iteratee.slice (başlangıç, sayfaSize)) çalıştırın –

1

Yürütme ve Numaratör'ü Yürütme çerçevesinden kullanmalısınız. Durumda da gerekir:

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 })) 

Umut bu