2016-02-19 36 views
1

我使用Stratio(0.11。)查詢MongoDB和Spark。我有興趣使用RDD(無DataFrame)。Spark:通過Stratio和RDD查詢Mongodb

我在做什麼現在的問題是:

val mongoRDD = new MongodbRDD(sqlContext, readConfig, new MongodbPartitioner(readConfig)) 
mongoRDD.foreach(println) 

,並顯示在一個正確的方式收集的內容。

有沒有辦法使用查詢(如String或通過QueryBuilder構建)與Stratio(在我的情況下查詢是$近類型)適用於MongodbRDD

+0

乍看之下它看起來並不像它。它將SQL謂詞向下推,但它不能用於'$ near'。 – zero323

+0

你仍然可以嘗試直接使用它:https://github.com/Stratio/Spark-MongoDB/blob/231e1fcb961868963bf7efcae04778d5a9c11f78/spark-mongodb/src/main/scala/com/stratio/datasource/mongodb/rdd/MongodbRDD。 scala#L37 – zero323

+0

是的,我在看「過濾器」,但唯一可以工作的是用「EqualTo」構建所有查詢。有點奇怪。 – Randomize

回答

3

正如@ zero323已經暗示,這樣做的方法是使用filters參數。這些過濾器由庫進行檢查,並與MongoDB QueryBuilder可用過濾器進行匹配。

從火花MongoDB的source code

sFilters.foreach { 
    case EqualTo(attribute, value) => 
     queryBuilder.put(attribute).is(checkObjectID(attribute, value)) 
    case GreaterThan(attribute, value) => 
     queryBuilder.put(attribute).greaterThan(checkObjectID(attribute, value)) 
    case GreaterThanOrEqual(attribute, value) => 
     queryBuilder.put(attribute).greaterThanEquals(checkObjectID(attribute, value)) 
    case In(attribute, values) => 
     queryBuilder.put(attribute).in(values.map(value => checkObjectID(attribute, value))) 
    case LessThan(attribute, value) => 
     queryBuilder.put(attribute).lessThan(checkObjectID(attribute, value)) 
    case LessThanOrEqual(attribute, value) => 
     queryBuilder.put(attribute).lessThanEquals(checkObjectID(attribute, value)) 
    case IsNull(attribute) => 
     queryBuilder.put(attribute).is(null) 
    case IsNotNull(attribute) => 
     queryBuilder.put(attribute).notEquals(null) 
    case And(leftFilter, rightFilter) if !parentFilterIsNot => 
     queryBuilder.and(filtersToDBObject(Array(leftFilter)), filtersToDBObject(Array(rightFilter))) 
    case Or(leftFilter, rightFilter) if !parentFilterIsNot => 
     queryBuilder.or(filtersToDBObject(Array(leftFilter)), filtersToDBObject(Array(rightFilter))) 
    case StringStartsWith(attribute, value) if !parentFilterIsNot => 
     queryBuilder.put(attribute).regex(Pattern.compile("^" + value + ".*$")) 
    case StringEndsWith(attribute, value) if !parentFilterIsNot => 
     queryBuilder.put(attribute).regex(Pattern.compile("^.*" + value + "$")) 
    case StringContains(attribute, value) if !parentFilterIsNot => 
     queryBuilder.put(attribute).regex(Pattern.compile(".*" + value + ".*")) 
    case Not(filter) => 
     filtersToDBObject(Array(filter), true) 
    } 

正如你所看到的,near不被應用,但它似乎是它可以自QueryBuilderoffers methods to use that MongoDB function很容易地添加到連接器的功能。

您可以嘗試修改連接器。不過,我會盡力實施它,並在接下來的日子裏做一個PR。

編輯:

一個PR has been opened包括描述$near所以你可以使用MongodbRdd作爲源過濾器類型:

val mongoRDD = new MongodbRDD(
    sqlContext, 
    readConfig, 
    new MongodbPartitioner(readConfig), 
    filters = FilterSection(Array(Near("x", 3.0, 4.0)))) 
) 
+0

是的,我已經看過GitHub的那部分代碼。理想的情況是,只需要有一個「setQuery」方法,可以將查詢生成的查詢通過QueryBuilder或文本字符串正常傳遞。 – Randomize

+0

@Randomize這是可行的。然而,它更容易添加「近」過濾器 –

+0

是的,我同意(雖然有近不同類型的查詢)。順便說一句,他們正在使用的抽象是將代碼耦合到特定版本的mongodb-java-driver,因爲QueryBuilder已經將API從2. *更改爲3. *。 – Randomize