Scala Salat BasicDBObject cannot be cast to - scala

I've spent so much time and still don't understand what the problem here.
So I have a collection that data looks like:
{ "_id" : "someId", "employment" : { "data" : [
{ "retrieved" : { "$date" : "2015-03-12T14:39:41.214Z"} , "value" : { "city" : "someSity" , "fromMonth" : 0 , "name" : "someName" , "fromYear" : 2011 , "toMonth" : 0 , "speciality" : "someSpeciality"}},
{ "retrieved" : { "$date" : "2015-03-12T14:39:41.214Z"} , "value" : { "city" : "someSity" , "fromMonth" : 7 , "name" : "someName" , "fromYear" : 2013 , "toMonth" : 7 , "toYear" : 2014 , "speciality" : "someSpeciality"}},
{ "retrieved" : { "$date" : "2015-03-12T14:39:41.214Z"} , "value" : { "city" : "someSity" , "fromMonth" : 10 , "name" : "someName" , "fromYear" : 2010 , "toMonth" : 10 , "toYear" : 2010 , "speciality" : "someSpeciality"}}
{ "retrieved" : { "$date" : "2015-03-12T14:39:41.214Z"} , "value" : { "fromMonth" : 2 , "name" : "someName" , "fromYear" : 2007 , "toMonth" : 2 , "toYear" : 2010 , "speciality" : "someSpeciality"}}
]}}
also I have SalatDAO for that collection:
object ProfileDAO extends SalatDAO[Profile, ObjectId](
collection = MongoFactory.getDB("profiles"))
and ofcourse a bunch of case class:
case class Profile(
#Key("_id") id: String,
employment: Option[ListField[Employment]]
case class ListField[T](
data: List[Value[T]])
case class Value[T](
value: Option[T],
retrieved: Option[Instant],
deleted: Option[Instant])
and finally Employment class:
case class Employment(
name: Option[String],
country: Option[String],
city: Option[String],
fromMonth: Option[Int],
toMonth: Option[Int],
fromYear: Option[Int],
toYear: Option[Int],
speciality: Option[String]
)
Byt when I try do something like this:
ProfileDAO.findAll().take(20).map(
profile => profile.employment.map(
employment => employment.data.map(
employmentData => employmentData.value.name)))
.foreach(println)
I get Exception: com.mongodb.BasicDBObject cannot be cast to com....Employment
Only one idea I have - some data in DBCollection don't match with Employment class, but there is Option[] evrywhere, so...

Go to where it's blowing up and print the _id value of the document that's failing to deserialize?

Related

How to create a compound index for speicifc documents in mongodb

I'm running MongoDB 4.2, see below how my documents look like:
{
"_id" : ObjectId("61e8e5b72e74b7fc3e16b632"),
"1" : 2,
"age_upon_outcome" : "1 year",
"animal_id" : "A725717",
"animal_type" : "Cat",
"breed" : "Domestic Shorthair Mix",
"color" : "Silver Tabby",
"date_of_birth" : "2015-05-02",
"datetime" : "2016-05-06 10:49:00",
"monthyear" : "2016-05-06T10:49:00",
"name" : "",
"outcome_subtype" : "SCRP",
"outcome_type" : "Transfer",
"sex_upon_outcome" : "Spayed Female",
"location_lat" : 30.6525984560228,
"location_long" : -97.7419963476444,
"age_upon_outcome_in_weeks" : 52.9215277777778
}
Bottom line is that I need to create a compound index that will improve the performance of queries looking for breeds that have an “outcome_type” of “Transfer”, and I'm not sure of how to narrow down the command below to only documents with outcome_type=Transfer
db.collection.createIndex( { breed: 1 } )
Would be this one:
db.collection.createIndex(
{ breed: 1 },
{ partialFilterExpression: { outcome_type: 'Transfer' } }
)

Casbah cas from BasicDBObject to my type

I have a collection in the database that looks like below:
Question
{
"_id" : ObjectId("52b3248a43fa7cd2bc4a2d6f"),
"id" : 1001,
"text" : "Which is a valid java access modifier?",
"questype" : "RADIO_BUTTON",
"issourcecode" : true,
"sourcecodename" : "sampleques",
"examId" : 1000,
"answers" : [
{
"id" : 1,
"text" : "private",
"isCorrectAnswer" : true
},
{
"id" : 2,
"text" : "personal",
"isCorrectAnswer" : false
},
{
"id" : 3,
"text" : "protect",
"isCorrectAnswer" : false
},
{
"id" : 4,
"text" : "publicize",
"isCorrectAnswer" : false
}
]
}
I have a case class that represents both the Question and Answer. The Question case class has a List of Answer objects. I tried converting the result of the find operation to convert the DBObject to my Answer type:
def toList[T](dbObj: DBObject, key: String): List[T] =
(List[T]() ++ dbObject(key).asInstanceOf[BasicDBList]) map { _.asInstanceOf[T]}
The result of the above operation when I call it like
toList[Answer](dbObj, "answers") map {y => Answer(y.id,y.text, y.isCorrectAnswer)}
fails with the following exception:
com.mongodb.BasicDBObject cannot be cast to domain.content.Answer
Why should it fail? Is there a way to convert the DBObject to Answer type that I want?
You have to retrieve values from BasicDBObject, cast them and then populate the Answer class:
Answer class:
case class Answer(id:Int,text:String,isCorrectAnswer:Boolean)
toList, I changed it to return List[Answer]
def toList(dbObj: DBObject, key: String): List[Answer] = dbObj.get(key).asInstanceOf[BasicDBList].map { o=>
Answer(
o.asInstanceOf[BasicDBObject].as[Int]("id"),
o.asInstanceOf[BasicDBObject].as[String]("text"),
o.asInstanceOf[BasicDBObject].as[Boolean]("isCorrectAnswer")
)
}.toList

mongoDb shows data by find in wrong order

i have table in mongoDB and I want to fetch data with followed order:
I have collection that has array of elements: _id, address, locname, loctype, id_double,
I want to get all array but with different element order like:
id_double, address, loctype, locname
So I wrote query:
db.coll.find({},{"_id":0, "id_double":1, "address":1, "loctype":1, "locname":1})
But got wrong order:
{ "loctype" : "Hospital", "locname" : "Alex", "address" : "Alrad", "id_double" : 21 }
{ "address" : "Bukit", "id_double" : 1, "locname" : "KKH", "loctype" : "Clinic/Hospital" }
{ "address" : "Thirdenue", "id_double" : 2, "locname" : "Singae", "loctype" : "Clinic/Hospital" }
{ "address" : "Avenue", "id_double" : 3, "locname" : "Nation", "loctype" : "Clinic/Hospital" }
{ "address" : "tal Drive", "id_double" : 4, "locname" : "SGH", "loctype" : "Clinic/Hospital" }
[Edit]
I used mySql -> mongodb converter
And seems that above mentioned syntax valid and must return data in the same order
Did I miss something?
Thanks,
Seems you missed the call to sort, e.g. like so:
db.coll.find().sort({id_double: 1, address: 1, loctype: 1, locname: 1})

Errors while creating a collection in MongoDB

I am new to MongoDB. I am not able to create a collection. It gives a sentence in the mongo shell - Display all 169 possibilities? (y or n). The code is -
db.Lead.insert(
{ LeadID: 1,
MasterAccountID: 100,
LeadName: 'Sarah',
LeadEmailID : 'sarah#hmail.com',
LeadPhoneNumber : '2132155445',
Details : [{ StateID: 1,
TaskID : 1,
Assigned By : 1001,
TimeStamp : '10:00:00',
StatusID : 1 }
]
}
)
Not sure what the issue is. Please help me out with the same.
Regards.
Apart from the fact there is a space in Assigned By everything looks good.
I am able to insert it properly.
> db.Lead.find().pretty()
{
"_id" : ObjectId("517ebe75278e0557fd167eb7"),
"LeadID" : 1,
"MasterAccountID" : 100,
"LeadName" : "Sarah",
"LeadEmailID" : "sarah#hmail.com",
"LeadPhoneNumber" : "2132155445",
"Details" : [
{
"StateID" : 1,
"TaskID" : 1,
"AssignedBy" : 1001,
"TimeStamp" : "10:00:00",
"StatusID" : 1
}
]
}

MongoDB - how to query for a nested item inside a collection?

I have some data that looks like this:
[
{
"_id" : ObjectId("4e2f2af16f1e7e4c2000000a"),
"advertisers" : [
{
"created_at" : ISODate("2011-07-26T21:02:19Z"),
"category" : "Infinity Pro Spin Air Brush",
"updated_at" : ISODate("2011-07-26T21:02:19Z"),
"lowered_name" : "conair",
"twitter_name" : "",
"facebook_page_url" : "",
"website_url" : "",
"user_ids" : [ ],
"blog_url" : "",
},
and I was thinking that a query like this would give the id of the advertiser:
var start = new Date(2011, 1, 1);
> var end = new Date(2011, 12, 12);
> db.agencies.find( { "created_at" : {$gte : start , $lt : end} } , { _id : 1 , program_ids : 1 , advertisers { name : 1 } } ).limit(1).toArray();
But my query didn't work. Any idea how I can add the fields inside the nested elements to my list of fields I want to get?
Thanks!
Use dot notation (e.g. advertisers.name) to query and retrieve fields from nested objects:
db.agencies.find({
"advertisers.created_at": {
$gte: start,
$lt: end
}
},
{
_id: 1,
program_ids: 1,
"advertisers.name": 1
}
}).limit(1).toArray();
Reference: Retrieving a Subset of Fields
and Dot Notation
db.agencies.find(
{ "advertisers.created_at" : {$gte : start , $lt : end} } ,
{ program_ids : 1 , advertisers.name : 1 }
).limit(1).pretty();
There is one thing called dot notation that MongoDB provides that allows you to look inside arrays of elements. Using it is as simple as adding a dot for each array you want to enter.
In your case
"_id" : ObjectId("4e2f2af16f1e7e4c2000000a"),
"advertisers" : [
{
"created_at" : ISODate("2011-07-26T21:02:19Z"),
"category" : "Infinity Pro Spin Air Brush",
"updated_at" : ISODate("2011-07-26T21:02:19Z"),
"lowered_name" : "conair",
"twitter_name" : "",
"facebook_page_url" : "",
"website_url" : "",
"user_ids" : [ ],
"blog_url" : "",
},
{ ... }
If you want to go inside the array of advertisers to look for the property created_at inside each one of them, you can simply write the query with the property {'advertisers.created_at': query} like follows
db.agencies.find( { 'advertisers.created_at' : { {$gte : start , $lt : end} ... }