BasicBSONList can only work with numeric keys, not: [_id] - mongodb

I am trying to insert multiple records to MongoDB at once , so for this i created a javaBean for each record to be inserted and added them to ArrayList .
And finally from the ArrayList , i am trying to perform a insert operation as shown below
public void insert(ArrayList<QuoteReportBean> quotelist) {
BasicDBList totalrecords = new BasicDBList();
StringBuffer sb = new StringBuffer();
int valuecount=0;
for (QuoteReportBean reportbean: quotelist) {
valuecount++;
BasicDBObject dbrecord = new BasicDBObject();
dbrecord.append("cust_id", reportbean.getCustomerId());
dbrecord.append("unique_symbol", reportbean.getUniqueSymbol());
sb.append(reportbean.getUniqueSymbol()+",");
dbrecord.append("exch", reportbean.getExchange());
dbrecord.append("access_time", reportbean.getDate());
totalrecords.add(dbrecord);
}
WriteResult result = coll.insert(totalrecords,WriteConcern.NORMAL);
}
But i am the follwoing error
Exception in thread "taskExecutor-1" java.lang.IllegalArgumentException: BasicBSONList can only work with numeric keys, not: [_id]
at org.bson.types.BasicBSONList._getInt(BasicBSONList.java:159)
at org.bson.types.BasicBSONList._getInt(BasicBSONList.java:150)
at org.bson.types.BasicBSONList.get(BasicBSONList.java:104)
at com.mongodb.DBCollection.apply(DBCollection.java:501)
at com.mongodb.DBCollection.apply(DBCollection.java:491)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:195)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:180)
at com.mongodb.DBCollection.insert(DBCollection.java:58)
Could anybody please help me as how to resolve this ??

BasicDBList can't be used to do inserts of multiple documents, it's only used for arrays inside a single document. To do a bulk insert, you need to pass an array of DBObjects into the insert method instead.
I changed your code to do this, and it worked without error:
StringBuffer sb = new StringBuffer();
int valuecount = 0;
final QuoteReportBean[] quotelist = {new QuoteReportBean()};
DBObject[] totalrecords = new BasicDBObject[quotelist.length];
for (int i = 0; i < quotelist.length; i++) {
QuoteReportBean reportbean = quotelist[i];
valuecount++;
BasicDBObject dbrecord = new BasicDBObject();
dbrecord.append("cust_id", reportbean.getCustomerId());
dbrecord.append("unique_symbol", reportbean.getUniqueSymbol());
sb.append(reportbean.getUniqueSymbol() + ",");
dbrecord.append("exch", reportbean.getExchange());
dbrecord.append("access_time", reportbean.getDate());
totalrecords[i] = dbrecord;
}
WriteResult result = coll.insert(totalrecords, WriteConcern.NORMAL);

Related

Android SQLite not returning data for given search term

I am trying to build a search interface but the SQLite database returns nothing here is the code for search function
public List<DiaryModel> searchData(String srchTerm){
List<DiaryModel> data2=new ArrayList<>();
SQLiteDatabase db1 = this.getWritableDatabase();
String sql="SELECT * FROM "+DB_TABLE+" WHERE "+KEY_HEADING+" LIKE '"+srchTerm+"%'";
Cursor cursor2 =db1.rawQuery(sql,null);
cursor2.moveToFirst();
StringBuilder stringBuffer2;
stringBuffer2 = new StringBuilder();
DiaryModel diaryModel2;
while (cursor2.moveToNext()){
diaryModel2 = new DiaryModel();
String heading = cursor2.getString(cursor2.getColumnIndexOrThrow("heading"));
String desc = cursor2.getString(cursor2.getColumnIndexOrThrow("desc_"));
diaryModel2.setHeading(heading);
diaryModel2.setDesc(desc);
stringBuffer2.append(diaryModel2);
data2.add(diaryModel2);
}
return data2;
}
but when I print everything the Database returns data, here is the code for get Data used for printing data present in Database
public List<DiaryModel> getdata(){
List<DiaryModel> data=new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor =db.rawQuery("SELECT * FROM diary_db", null);
cursor.moveToFirst();
StringBuilder stringBuffer = new StringBuilder();
DiaryModel diaryModel;
while (cursor.moveToNext()){
diaryModel = new DiaryModel();
String heading = cursor.getString(cursor.getColumnIndexOrThrow(KEY_HEADING));
String desc = cursor.getString(cursor.getColumnIndexOrThrow(KEY_DESC));
diaryModel.setHeading(heading);
diaryModel.setDesc(desc);
stringBuffer.append(diaryModel);
data.add(diaryModel);
}
return data
}
The thing is only this SQL statement is working
SELECT * FROM diary_db
and if any condition is put nothing returns.
There is something that you are doing wrong in both methods:
cursor.moveToFirst();
and then:
while (cursor.moveToNext()){
.................
}
This way you miss the 1st row of the results, because after you move the cursor to the 1st row, you move once again to the next row.
So delete this:
cursor.moveToFirst();
from both methods.

The method aggregate(List<? extends Bson>) in the type MongoCollection<Document> is not applicable for the arguments (BasicDBObject)

I am new to MongoDB. I am getting an error in loginCollection.aggregate stating:
The method aggregate(List) in the type MongoCollection is not applicable for the arguments (BasicDBObject)
Following is my code snippet. Thanks in advance.
public MonthlyLoginCount monthlyLoginCount() {
MonthlyLoginCount monthlyLoginCount = new MonthlyLoginCount();
Map<String, Long> map = new HashMap<String, Long>();
MongoClient mongo = new MongoClient(dataSource, 27017);
MongoCollection<Document> loginCollection = mongo.getDatabase(mongoDataBase).getCollection(loginDetailsCollection);
AggregationOutput logincount = loginCollection.aggregate(new BasicDBObject("$group",
new BasicDBObject("_id", "$email_id").append("value", new BasicDBObject("$push", "$value"))));
Iterator<DBObject> results = logincount.results().iterator();
while (results.hasNext()) {
try {
Object str = results.next().get("_id");
long count = loginCollection.count(new BasicDBObject("email_id", str.toString()));
System.out.println("email id:: " + str.toString() + " count: " + count);
map.put(str.toString(), count);
} catch (Exception e) {
e.printStackTrace();
}
}
mongo.close();
monthlyLoginCount.setMap(map);
return monthlyLoginCount;
}
It's a little bit tricky to answer this without knowing what version of the MongoDB Java driver you are using however...
Since sometime in the 2.x train the aggregate() method has accepted a List. For example:
// in 2.14
AggregationOutput aggregate(List<DBObject> pipeline)
// in 3.x
AggregateIterable<TDocument> aggregate(List<? extends Bson> pipeline);
The one and only argument is a List, this list represents the stages in an aggregation pipeline. For example:
AggregateIterable<Document> documents = collection.aggregate(Arrays.asList(
new Document("$match", theMatchDocument),
new Document("$project", theProjectionDocument)
));
The exception message included in your question:
"The method aggregate(List) in the type MongoCollection is not applicable for the arguments (BasicDBObject)"
... implies that you are attempting to call aggregate(List) and the assignment of that to a AggregationOutput makes me suspect that you are using v2.1x (see the API docs. If so, then the example posted in your question could be restated as follows:
AggregationOutput logincount = loginCollection.aggregate(Arrays.asList(
new BasicDBObject("$group", new BasicDBObject("_id", "$email_id").append("value", new BasicDBObject("$push", "$value")))
));

Linq query in stored procedure result set Ado.Net

I have a stored procedure with multiple joins, pulling all the data into a resultset I.e in dataset, now I want to write a linq query over it. How can I do that?
I am expecting:
IEnumerable<SomeType> result;
[where I need to know how the Properties of SomeType are defined.]
This is what I have tried but it does not look efficient.
SqlCommand cmd = new SqlCommand("Select top 10 * from trade");
cmd.Connection = con;
if (con.State != ConnectionState.Open)
{
con.Open();
}
SqlDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
var result = dt.AsEnumerable();
string valresukir = string.Empty;
var sortResult = result.OrderBy(x => Convert.ToInt32(x["trade_num"]) > 12);
string valuedata = string.Empty;
foreach (var i in sortResult)
{
valuedata += i["trade_num"].ToString();
}
to can write linq query on data table like
var data= from dataRow in dt.AsEnumerable()
where dataRow.Field<int>("trade_num") > 12
select dataRow
if trade_num is integer . Take it as a example and add your conditions accordingly.
Hope it will help you.

MongoDB Reinitialize BulkWriteOperation after execute

I first initialie the BulkWriteOperation and add several inserts to it through a for loop. Then I do execute. I then reinitialize the BulkWriteOperation and try to add more insert but I keep getting:
java.lang.IllegalStateException: already executed
My Code:
BulkWriteOperation builder = coll.initializeOrderedBulkOperation();
for( int i = 0; i < 10; i++ ) {
BasicDBObject doc = new BasicDBObject("Something", something);
builder.insert(doc);
}
builder.execute();
builder = coll.initializeOrderedBulkOperation();
for( int i = 0; i < 10; i++ ) {
BasicDBObject doc = new BasicDBObject("Something", something);
builder.insert(doc);
}
builder.execute();
There isn't a way to reset the existing BulkWriteOperation object after executing it, so you just need to create a new one like this:
builder = coll.initializeOrderedBulkOperation();

DBCursor hasNext seems to only return 1 result when it should return 2

I have the following...
DBCollection dbc = test.getCollection();
double count = dbc.count();
DBCursor cursor = dbc.find();
StringBuilder sb = new StringBuilder();
if( cursor.hasNext() )
sb.append(cursor.next().toString());
This outputs only one record but shows a count of 2. This one seems to work...
DBCollection dbc = test.getCollection();
double count = dbc.count();
DBCursor cursor = dbc.find();
StringBuilder sb = new StringBuilder();
for(double i = 0.0; i<count; i++)
sb.append(cursor.next().toString());
What am I missing
do you mean to use
while( cursor.hasNext() )
sb.append(cursor.next().toString());
Right now, you use 'if' but you probably want 'while'.