Invalid JSON number '2L'. shard key being serialized to number but defined as string? - mongodb

Exception:
System.FormatException: Invalid JSON number '2L'.
at MongoDB.Bson.IO.JsonScanner.GetNumberToken(JsonBuffer buffer, Int32 firstChar)
at MongoDB.Bson.IO.JsonScanner.GetNextToken(JsonBuffer buffer)
at MongoDB.Bson.IO.JsonReader.PopToken()
at MongoDB.Bson.IO.JsonReader.ReadBsonType()
at MongoDB.Bson.Serialization.Serializers.BsonDocumentSerializer.DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
Shard key definition, which is a composite key created by the constructor;
public string ShardKey { get; set; }
Query code:
public virtual async Task<ICollection<City>>(City city)
{
string shardKey = city.CityNumber + city.ShortName;
return await MongoDb.CitiesCollection.Aggregate().Match({
"{ 'Time': { $elemMatch: { $eq: 0 } }," + " ShardKey: " + shardKey + " }")
.ToListAsync();
}
Why does this fail?

Wrap the value containing the number like:
" ShardKey: '" + shardKey + "' }"
with single quotation marks.
I haven't been able to find this documented anywhere though. But it makes the my integration test run so :)

Related

How to make native query for nested projection in Spring Data JPA

I need to write a native query for my projection with nested interfaces.
My TransactionView interface:
public interface TransactionView {
Long getId();
TransactionType getType();
LocalDate getDate();
AccountProjection getAcc1();
AccountProjection getAcc2();
interface AccountProjection {
String getName();
CurrencyName getCurrencyCode();
BigDecimal getBalance();
}
BigDecimal getAmount();
PartnerView getPartner();
interface PartnerView {
String getName();
}
String getComment();
CategoryView getCategory();
interface CategoryView {
String getName();
}
}
JpaRepository:
public interface TransactionsRepository extends JpaRepository<Transaction, Long> {
List<TransactionView> findByAcc1PersonIdOrderByDateDesc(int personId);
}
This approach works good and I get JSON like this:
[{
"id":34,
"type":"TRANSFER",
"comment":"test comment",
"date":"2022-12-23",
"amount":200.00,
"acc2":
{
"name":"cash",
"currencyCode":"USD",
"balance":200.00
},
"acc1":
{
"name":"test acc",
"currencyCode":"USD",
"balance":700.00
},
"partner":null,
"category":null
},
{
"id":20,
"type":"EXPENCE",
"comment":"",
"date":"2022-12-13",
"amount":33.07,
"acc2":null,
"acc1":
{
"name":"cash",
"currencyCode":"BYN",
"balance":322.33
},
"partner":
{
"name":"bmw"
},
"category":
{
"name":"auto"
}
}]
But Hibernate generates a very complex query with a lot of extra columns fetching.
My native query returns null nested objects:
#Query(value = "SELECT t.id AS id, " +
"t.transaction_type AS type, " +
"t.transaction_date AS date, " +
"t.amount AS amount, " +
"t.comment AS comment, " +
"a1.balance AS acc1Balance, " +
"a1.currency_code AS acc1CurrencyCode, " +
"a1.name AS acc1Name, " +
"a2.balance AS acc2Balance, " +
"a2.currency_code AS acc2CurrencyCode, " +
"a2.name AS acc2Name, " +
"par.name AS partnerName, " +
"cat.name AS categoryName, " +
"cat.category_type AS categoryType " +
"FROM transaction t " +
"LEFT OUTER JOIN account a1 ON t.acc1_id=a1.id " +
"LEFT OUTER JOIN person per ON a1.person_id=per.id " +
"LEFT OUTER JOIN account a2 ON t.acc2_id=a2.id " +
"LEFT OUTER JOIN partner par ON t.partner_id=par.id " +
"LEFT OUTER JOIN category cat ON t.category_id=cat.id " +
"WHERE per.id=?1 ORDER BY t.transaction_date DESC", nativeQuery = true)
List<TransactionView> findByAcc1PersonIdOrderByDateDescTest(int personId);
[{
"id":34,
"type":"TRANSFER",
"comment":"test comment",
"date":"2022-12-23",
"amount":200.00,
"acc2":null,
"acc1":null,
"partner":null,
"category":null
},
{
"id":20,
"type":"EXPENCE",
"comment":"",
"date":"2022-12-13",
"amount":33.07,
"acc2":null,
"acc1":null,
"partner":null,
"category":null
}]
Also I tried approach from Peter Gyschuk, but it doesn't work.
How can I solve it using native query?

set boolean value in sqlite android

I have column which is supposed to contain the true and false value in db. I understand that they should be in form of 0 and 1. I have an int column "status" but it always returns zero.
#Override
public void onCreate(SQLiteDatabase db) {
String create_table = "CREATE TABLE " + TABLE_NAME + "( "
+ "ID INTEGER PRIMARY KEY ,"
+ VALUE + " TEXT NOT NULL, "
+ STATUS + " INTEGER NOT NULL)";
db.execSQL(create_table);
}
public int getStatus(String _id,int status)
{
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT " + STATUS + " FROM "
+TABLE_NAME+" WHERE " + _ID +" =? " , new String[] {_id});
if(cursor.moveToFirst()){
return cursor.getInt(cursor.getColumnIndex(STATUS));
} else {
return 0;
}
}
I need to set to true in the case below but item_status returns zero everytime. I checked the db and there is NULL in the whole status column.
if (success) {
status = 1;
int item_status = db.getStatus(fetchId(),status);
Toast.makeText(this, " item_status " + item_status , Toast.LENGTH_SHORT).show();
}

TypeScript interface type checking from the beginning tutorial

I've just started learning TypeScript and I'm having a hard time wrapping my head around an interface behavior from the beginning tutorial on http://www.typescriptlang.org/Playground/#tut=ex5
As I understand it, the interface should enforce the type of the parameters, however this particular line throws me off
var user = new Student("Jane", "M.", "User");
It compiles correctly and all is well, but when I modify it to
var user = new Student(1, 2, 3);
it also compiles just fine.
Could anyone elaborate why it's working ?
I understand that this is a beginners question but I could not find any info on this searching online and I don't have any TypeScript experts around me.
Thanks in advance,
Eugene
The type of the Student constructor parameters is any because there is no type annotation:
class Student {
fullname : string;
constructor(public firstname, public middleinitial, public lastname) {
this.fullname = firstname + " " + middleinitial + " " + lastname;
}
}
If we change it to have some type annotations, we'll get an error:
class Student {
fullname : string;
constructor(public firstname: string, // <-- add ': string' here
public middleinitial: string, // and here
public lastname: string) { // and here
this.fullname = firstname + " " + middleinitial + " " + lastname;
}
}
var x = new Student(1, 2, 3); // Error

How to write a dynamic where 'like' query in Entity framework?

Here is my code:
//order my baselist is context.Entity
public static GridData Getdata<T>(ObjectSet<T> baseList,
int currentPage,
int rowsPerPage,
string sortcolumn,
string sortord,
string searchQuery,
string searchColumns)where T: class{
var query = baseList.OrderBy("it." + sortcolumn + " " + sortord);
string strPredicate = string.Empty;
if (!string.IsNullOrEmpty(searchColumns))
{
strPredicate = "it." + searchColumns + " LIKE #" + searchColumns + " ";
query = baseList.Where(strPredicate, new ObjectParameter(searchColumns, searchQuery)).OrderBy("it." + sortcolumn + " " + sortord);
}
}
My problem is i am trying to write down or form a like query in entity framework and seems like it does not support it.
You can use .Contains which is the LIKE operator equivalent in entity framework.
you can use this
query = baseList.Where(baseli=>baseli.Contains(searchColumns )).OrderBy("it." + sortcolumn + " " + sortord);
:)

Entity SQL Datetime Syntax error

Anyone know What is wrong with my syntax here? I am making dynamic eSQL Queries and running into an error when trying to make where condition for DateTime data type. This is the error:
The query syntax is not valid. Near term '2011', line 1, column 135.
If it matters the DateTime type in my entity is actually nullable DateTime?
However, I thought this is the correct syntax from everything I've read.
Here is the code:
List<EntityFilter<FirstRead>> filters = new List<EntityFilter<FirstRead>>()
{
new EntityFilter<StudyFirstRead> { PropertyName = "username", OpType = ExpressionType.Equal, Value = "cwoodhouse" },
new EntityFilter<StudyFirstRead> { PropertyName = "FirstRead", OpType = ExpressionType.LessThan, Value = "DATETIME'2011-02-01 00:00'" }
};
Where EntityFilter is:
public class EntityFilter<T>
{
public string PropertyName { get; set; }
public ExpressionType OpType { get; set; }
public object Value { get; set; }
And I am building dynamic queries like so:
StringBuilder builder = new StringBuilder();
int counter = 0;
string baseStr = #"SELECT VALUE val FROM " + contextName + "." + tableName + " AS val WHERE val.";
builder.Append(baseStr);
foreach (EntityFilter<T> filter in filters)
{
//builder.Append(filter.PropertyName + " " + filter.OpTypeString() + " #p" + counter);
builder.Append(filter.PropertyName + " " + filter.OpTypeString() + "'" + filter.Value + "'");
counter++;
if (counter < filters.Count)
builder.Append(" AND val.");
else
{
break;
}
}
return builder.ToString();
It actually is the correct syntax for entity SQL (different than regular SQL or T-SQL).
Turns out the problem was too many single quotes, because I had them in both the EntityFilter object and the method that built the dynamic query.
according to you code the end of your SQL statement would produce something like
AND val.FirstRead = 'DATETIME'2011-02-01 00:00''
when executed you will get error
Error 102: Incorrect syntax near '2011'.
obviously that is not syntactically correct SQL, the quick fix whould be to have your filters collection as such:
List<EntityFilter<FirstRead>> filters = new List<EntityFilter<FirstRead>>() {
new EntityFilter<StudyFirstRead> {
PropertyName = "username",
OpType = ExpressionType.Equal,
Value = "cwoodhouse"
}, new EntityFilter<StudyFirstRead> {
PropertyName = "FirstRead",
OpType = ExpressionType.LessThan,
Value = "2011-02-01 00:00"
}
};