How to add unique query in updateAll psql - postgresql

let query=`created BETWEEN NOW()::DATE-EXTRACT(DOW FROM NOW())::INTEGER-7 AND NOW()::DATE-EXTRACT(DOW from NOW())::INTEGER`;
let result = await this.sampleRequestsRepository.updateAll(
{
`${query}`
},
{ "deleatedAt": true },
);
console.log(result );
I am trying to run this, but it does not allow me to add a query like this. I want to run unique query inside updateAll.

we can use js and Between ,
let today = new Date();
let weekAgo = new Date();
weekAgo.setDate(weekAgo.getDate() - 7);
let result = await this.sampleRequestsRepository.updateAll(
`{
updatedAt: Between(weekAgo, today)
},
{ "deleatedAt": true },
);`,

Related

`find_one` does not give ObjectId in proper format

As the title states, here is the following code.
let users_coll = db
.database("foo")
.collection::<bson::oid::ObjectId>("users");
let user_id = users_coll
.find_one(
doc! { "email": &account.email },
mongodb::options::FindOneOptions::builder()
.projection(doc! { "_id": 1i32 })
.build(),
)
.await?
.unwrap();
But it fails at ? operator with the following mongodb::error::Error,
Error { kind: BsonDeserialization(DeserializationError { message: "expected map containing extended-JSON formatted ObjectId, instead found { \"_id\": ObjectId(\"62af199df4a16d3ea6056536\") }" }), labels: {}, wire_version: None, source: None }
And it is right. Given ObjectId should be in this format,
{
"_id": {
"$oid": "62af199df4a16d3ea6056536"
}
}
But I do not know how to handle this. Any help is appreciated.
Have a good day!
Your users collection isn't a collection of ObjectIds, it's actually a collection of documents which each contain an ObjectId. To let Rust know what to do with those, you should create a struct which represents the document, or at least the parts which you care about getting back from your query, and tell your collection to de-serialize into that struct:
use mongodb::bson::oid::ObjectId;
use serde::{Serialize, Deserialize};
#[derive(Debug, Default, Serialize, Deserialize)]
struct User {
_id: ObjectId,
}
#[tokio::main]
async fn main() {
let users_coll = db
.database("foo")
.collection::<User>("users");
let user_id: ObjectId = users_coll
.find_one(
doc! { "email": &account.email },
mongodb::options::FindOneOptions::builder()
.projection(doc! { "_id": 1i32 })
.build(),
)
.await?
.unwrap()
._id;
}
By default, the BSON fields have to match the struct fields exactly (_id in this case), but I'm pretty sure serde has a way to change that if you don't like the leading underscore.

I have a database, if I want to retrieve a field of a specific document I can, but I would like to retrieve a field from the last document updated

In this way it works, I go to retrieve the field of that document (in this case the extranote), but what if I would only be interested in that field of the last document inserted chronologically?
I looked for similar examples but I wouldn't want just a few options, which I obviously don't know, to add when I create the db.
This model was created to read directly into the database without going through the App:
struct WorkoutModel: Identifiable,Codable {
//var id = UUID().uuidString
#DocumentID var id : String?
var extranote : String
var error: String = ""
}
struct SimpleEntry: TimelineEntry {
let date: Date
var deviceCount: Int
var deviceMake: String
var deviceModel: String
var deviceType: String
let configuration: ConfigurationIntent
var workoutData: WorkoutModel?
}
func fetchFromDB(completion: #escaping (WorkoutModel)->()){
let db = Firestore.firestore().collection("devices").document("lEp5impGTGeBmAEisQT")
db.getDocument { snap, err in
guard let doc = snap?.data() else {
completion(WorkoutModel(extranote: "", error: err?.localizedDescription ?? ""))
return
}
let extranote = doc["extranote"] as? String ?? ""
completion(WorkoutModel(extranote: extranote))
}
}
func getTimeline(for configuration: ConfigurationIntent, in context: Context,
completion: #escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting
from the current date.
let date = Date()
let nextUpdate = Calendar.current.date(byAdding: .minute, value: 5, to:date)!
fetchFromDB { work in
let entry = SimpleEntry(date: nextUpdate, deviceCount:
deviceCount,deviceMake: deviceMake,deviceModel: deviceModel,deviceType:
deviceType, configuration: configuration, workoutData: work)
entries.append(entry)
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
}
If you don't know the ID of the document to update, then you will need to query the collection for the document. If you don't have a field in that document that indicates the timestamp of its last update, then you won't be able to make that query at all. So, you will have to add a field to the document, and make sure it's populated with the current timestamp every time you write it. Then you can use that field to make the query if you want to update it again later.

Main thread messes up sorting

Dispatching the queue messes up the order in the array as noted below. I'm trying to rank the array and then be able to translate it. So far its not working:
let top5 = Array(labels.sorted{ $0.confidence > $1.confidence}.prefix(upTo:5))
for lulu in top5 {
let translator = ROGoogleTranslate()
var params = ROGoogleTranslateParams()
params.source = "en"
params.target = "es"
params.text = "\(String(describing: lulu.label))"
translator.translate(params: params, callback: { (result) in
DispatchQueue.main.async {
self.textUno.text = self.textUno.text! + "\(lulu.label)" + " \(lulu.confidence*100)\n"
self.textDos.text = self.textDos.text! + "\(result)\n"
self.view.addSubview(self.textUno)
self.view.addSubview(self.textDos)
}
})
}
If I try to put the sorting out of DispatchQueue.main.async then the translation won't be lined up with the right word.
How can I fix this so that the array is sorted and the translation matches up ?
Translate the array first before ranking them.
Make it simpler first and make sure it is working and then put all the parts together.
If you really want to do it this way you will need to put them into a temporary array after sorting them and then use that at the end.
This, as you said, will return a jumbled result.
The below example is pretty close, needs a bit of a polish but you should be able to do it from this.
let top5 = Array(labels.sorted{ $0.confidence > $1.confidence}.prefix(upTo:5))
var tmparr : []
var count: Int = 0
for lulu in top5 {
let translator = ROGoogleTranslate()
count = count + 1
var params = ROGoogleTranslateParams()
params.source = "en"
params.target = "es"
params.text = "\(String(describing: lulu.label))"
params.ordernumber = count
translator.translate(params: params, callback: { (result) in
tmparr.append[params]
})
}
DispatchQueue.main.async {
for lulunew in tmparr {
if (lulunew.ordernumber == correctindex){
self.textUno.text = self.textUno.text! + "\(lulu.label)" + " \(lulu.confidence*100)\n"
self.textDos.text = self.textDos.text! + "\(result)\n"
self.view.addSubview(self.textUno)
self.view.addSubview(self.textDos)
}
}
}

Intersection of 2 arrays and doing operation on each

The code below successfully take a list of favourites names and matches it to a smaller list of names, and upon each match or mismatch, it creates a new data struct indicating if it was favourited. (However this seem to be (N^2) complexity)
listOfNames.forEach {
var faved = false
if namesFavorited.contains($0) {
faved = true
}
let model = DetailNameModel(name: $0, favorited: faved)
detailNameModelArray.append(model)
}
Is there a better way to do this that can SCALE to 10s of thousands say down to N or NLogN?
You can use Set collection. It provides efficient ways to interact with collections. More detail here.
Updated code:
let listOfNames: Set = ["name1", "name2", "name3", "name4", "name5", "name6", "name7", "name8"]
let namesFavorited: Set = ["name2", "name3", "name5", "name6", "name8", "name9", "name10", "name11"]
let nonFav = listOfNames.subtracting(namesFavorited) // O(m*n)
let fav = listOfNames.intersection(namesFavorited) // O(m*n)
var detailNameModelArray: [DetailNameModel] = []
let nonFavDetailNames = nonFav.map { // O(nonFav.count)
DetailNameModel(name: $0, favorited: false)
}
detailNameModelArray.append(contentsOf: nonFavDetailNames)
let favDetailNames = fav.map { // O(fav.count)
DetailNameModel(name: $0, favorited: true)
}
detailNameModelArray.append(contentsOf: favDetailNames)
print(detailNameModelArray) // O(fav.count)
You can generate a lot of data and compare my method and yours. I think my method will win.

What's the difference and/or preferred way of updating a deep property?

This is a babel/ES7 question (for redux reducer use)
I want to update "dan" only in some properties. What's the preferred way with immutability mind?
It seems that only TRY 1 and TRY 3 merge/update correctly.
Is there any difference between the two? For me TRY 3 wins because it's the shortest (if no difference between TRY 1)
Thanks
const people = { byID: {
gaston : { name:'Gaston', age: 22 },
dan : { name: 'gaston', age: 44 }
}
}
const currentID = "dan"
///
// TRY 1
const thisID = {}
thisID[currentID] = {...people.byID[currentID],
age: 20,
sex: 'male',
}
const newPeople = {...people,
byID: {...people.byID,
...thisID
}
}
console.log( newPeople ) // OK
//
// TRY 2
const newPeople2 = {}
newPeople2.byID = {}
newPeople2.byID[currentID] = {}
newPeople2.byID[currentID]["age"] = 20
newPeople2.byID[currentID]["sex"] = "male"
const newPeople3 = {...people, ...newPeople2}
console.log( newPeople3 ) // NOPE (not merge)
//
// TRY 3
const newPeople4 = {...people}
newPeople4.byID = newPeople4.byID || {}
newPeople4.byID[currentID] = newPeople4.byID[currentID] || {}
newPeople4.byID[currentID]["age"] = 20
newPeople4.byID[currentID]["sex"] = "male"
console.log(newPeople4) // OK
Here are the outputs
TRY 1
{"byID":{"gaston":{"name":"Gaston","age":22},"dan":{"name":"gaston","age":20,"sex":"male"}}}
TRY 2
{"byID":{"dan":{"age":20,"sex":"male"}}}
TRY 3
{"byID":{"gaston":{"name":"Gaston","age":22},"dan":{"name":"gaston","age":20,"sex":"male"}}}
Using the spread operator, you can do:
const updatedPeople = {
byID: {
...people.byID,
dan: {
...people.byID.dan,
age: 20,
sex: "male"
}
}
};
If you need the id to be dynamic, using computed property keys (an other ES6 feature, part of destructuring):
const id = 'dan';
const updatedPeople = {
byID: {
...people.byID,
[id]: {
...people.byID[id],
age: 20,
sex: "male"
}
}
};
Those solutions are immutability full proof, though, if you're not familiar with ES6 syntax, they can be hard to read and if you have more complex data, you might consider using immutablejs (or some kind of immutable library)