how to use golang mongodb driver query $or with $and? - go

1.judge field label_status is exists, if exists is true find one record.
2.if field label_status exist is false. find one record label_status eq 1 and author
eq sample
i use the code:
bson.D{
{"$or", bson.D{{"label_status", bson.D{{"$exists", false}}}}},
{"$and", bson.A{bson.M{"label_status": Labeling}, bson.M{"annotator": "sample"}}},
}

err := collection.FindOne(context.Background(), bson.D{
{"$or", bson.D{{"label_status", bson.D{{"$exists", false}}}}},
{"$and", bson.A{bson.M{"label_status": Labeling}, bson.M{"annotator": "sample"}}},
}).Decode(&result)

Related

Why are these seemingly identical Golang structs not equal?

I'm trying to learn Golang testing.
I'm comparing 2 seemingly identical stucts but they are not equal. What is going wrong?
2020/01/22 17:10:10 ****2 cities[0] is type *main.City has &main.City{Name:"Boston", State:"", Country:"USA", Capital:true, Population:685000}
2020/01/22 17:10:10 ****2 expected is type *main.City has &main.City{Name:"Boston", State:"", Country:"USA", Capital:true, Population:685000}
2020/01/22 17:10:11 Preparing to DELETE 5 city docs
--- FAIL: TestCities (3.08s)
--- FAIL: TestCities/Test_POST_should_add_New_City (0.62s)
city_handlers_test.go:68: Why is ( cities[0] != expected )Boston was not added to Firestore:
got &{Boston USA true 685000}
want &{Boston USA true 685000}
FAIL
exit status 1
Here is the test:
// why don't these structs match?
log.Printf("****2 cities[0] is type %T has %#v \n", cities[0], cities[0])
log.Printf("****2 expected is type %T has %#v \n", expected, expected)
// why is this comparison failing when both are the same type with the same values?
if cities[0] != expected {
t.Errorf("Why is ( cities[0] != expected )Boston was not added to Firestore: \n got %v \n want %v", cities[0], expected)
}
You compare pointers, and it looks like they point to different objects. For the correct check, you should compare objects' fields.
This packages can help you to do this: reflect.DeepEqual(), testify.EqualValues(), cmp.Equal()
Example:
https://play.golang.org/p/09BYFeYj5xx

Make Firestore only return users with customer_id that is less than 1000

How do I extract the users in my db that has a customer_id with less than 8 digits?
I tried to do this:
iter := client.Collection("users").Where("customer_id", "<", "10000").Documents(ctx)
But that doesn't return anything, even though I know I have users that looks like this:
map[customer_id:111]
map[customer_id:123]
If I however do
iter := client.Collection("users").Where("customer_id", "==", "111").Documents(ctx)
.. it will find that document,
EDIT: I just noticed that customer_id is stored as a string.
Not a firestore user, but I found some info from https://cloud.google.com/firestore/docs/query-data/queries.
countryQuery := cities.Where("state", "==", "CA")
popQuery := cities.Where("population", "<", 1000000)
cityQuery := cities.Where("name", ">=", "San Francisco")
So I think you should just try:
iter := client.Collection("users").Where("customer_id", "<", 10000).Documents(ctx)
The reason for this to happen is because you are having the filed set as "string" instead of "number". I had replicated the use case scenario and those are my findings:
My Firestore database:
collection: users
>> document: "auto_id"
--customer_id: 111
>> document: "auto_id"
--customer_id: 123
>> document: "auto_id"
--customer_id: 4500
>> document: "auto_id"
--customer_id: 3500
I have setup in Firestore each customer_id as string. Then when using method Where("customer_id", "==", "111") will give me map[customer_id:111] but when using Where("customer_id", "<", "1000") or Where("customer_id", "<", 1000) will give me nothing as you described.
Then I went to Firestore and changed the type of each filed from string to number and executed the code again, so I got:
map[customer_id:111]
map[customer_id:123]
My full code example in GitHub that worked for me.

xslt/xquery for checking values of two attributes in if conditions

I am stuck at a place in my xquery. In the response i want to get back the phone numbers for each Type i.e. HOME and CELL , but only the ones which have highest sequence number .If there are two rows with PhoneType="HOME" , I want back the phone which has highest sequence of two i.e in my case Sequence="3".
With my xquery I am able to get back a phoneType="HOME" and the first row with type HOME. i am not able to add a condition to check the Sequence as well. Where and how can i add it. Please suggest. Thanks in advance
Part of my Xquery:
<acc:phones>
{
for $PersonPhonesRow in $PersonMaintenanceResponse/ns2:CMPersonService/ns2:CMPersonDetails/ns2:PersonPhones/ns2:PersonPhonesRow[#PhoneType="HOME"][1]
return
if(fn:data($PersonMaintenanceResponse/ns2:CMPersonService/ns2:CMPersonDetails/ns2:PersonPhones/ns2:PersonPhonesRow/#PhoneType="HOME"[1]))
then
<com:phone>
<com:type>{'HOME'}</com:type>
<com:phoneNumber>{fn:data($PersonMaintenanceResponse/ns2:CMPersonService/ns2:CMPersonDetails/ns2:PersonPhones/ns2:PersonPhonesRow[#PhoneType="HOME"][1]/#PhoneNumber)}</com:phoneNumber>
<com:carrier>{fn:data($PersonMaintenanceResponse/ns2:CMPersonService/ns2:CMPersonDetails/ns2:PersonPhones/ns2:PersonPhonesRow[#PhoneType="HOME"][1]/#Extension)}</com:carrier>
</com:phone>
else
()
}
</acc:phones>
Request:
<CMPerson xmlns="http://splwg.com/CMPerson.xsd">
<CMPersonService>
<CMPersonDetails>
<PersonPhones>
<PersonPhonesHeader PersonID="1234567890" LastSequenceNumber="9"/>
<PersonPhonesRow PersonID="1234567890" Sequence="1" PhoneType="HOME" IntlPrefix="" PhoneNumber="(850) 123-0000" Extension="" Version="12" PhoneAlgorithmParamValue="(999) 999-9999"/>
<PersonPhonesRow PersonID="1234567890" Sequence="2" PhoneType="CELL" IntlPrefix="" PhoneNumber="(850) 000-0000" Extension="" Version="3" PhoneAlgorithmParamValue="(999) 999-9999"/>
<PersonPhonesRow PersonID="1234567890" Sequence="3" PhoneType="HOME" IntlPrefix="" PhoneNumber="(850) 123-1111" Extension="ATT" Version="1" PhoneAlgorithmParamValue="(999) 999-9999"/>
<PersonPhonesRow PersonID="1234567890" Sequence="4" PhoneType="BUSN" IntlPrefix="" PhoneNumber="(904) 111-1111" Extension="" Version="3" PhoneAlgorithmParamValue="(999) 999-9999"/>
</PersonPhones>
</CMPersonDetails>
</CMPersonService>
</CMPerson>
Response required:
<acc:phones>
<com:phone xmlns:com="******">
<com:type>HOME</com:type>
<com:phoneNumber>(850) 123-1111</com:phoneNumber>
<com:carrier>ATT</com:carrier>
</com:phone>
<com:phone xmlns:com="******">
<com:type>CELL</com:type>
<com:phoneNumber>(904) 111-1111</com:phoneNumber>
<com:carrier></com:carrier>
</com:phone>
</acc:phones>
Query to be used:
let $PersonMaintenanceResponse := 'Your request'
let $uniqPhoneType :=distinct-values($PersonMaintenanceResponse/ns2:CMPersonService/ns2:CMPersonDetails/ns2:PersonPhones/ns2:PersonPhonesRow/#PhoneType)
for $each at $i in $uniqPhoneType
return
<acc:phones>
{
let $seq := $PersonMaintenanceResponse/ns2:CMPersonService/ns2:CMPersonDetails/ns2:PersonPhones/ns2:PersonPhonesRow[(#PhoneType = $each)]
let $maxValue := max($seq/#Sequence)
let $maxrow := $seq[#Sequence eq $maxValue]
return
<com:phone xmlns:com="*******">
<com:type>{$each}</com:type>
<com:phoneNumber>{$maxrow/#PhoneNumber}</com:phoneNumber>
<com:carrier>{$maxrow/#Extension}</com:carrier>
</com:phone>
}</acc:phones>

Golang Gorm db.raw with CloudSQL for Update SQL query not working?

I have this SQL query, which in isolation works fine with 2 rows affected absolutely fine
update chores set life_status ='Processing' where life_status = 'Active' and chore_type ='Shared' and money_assigned > 0
But when I try gorm's execution variant statements in golang i.e.
err := h.db.Raw("update chores set life_status ='Processing' where life_status = 'Active' and chore_type ='Shared' and money_assigned > ? ", 0).Error
OR
numRecsToProcess := h.db.Raw("update chores set life_status ='Processing' where life_status = 'Active' and chore_type ='Shared' and money_assigned > ? ", 0).RowsAffected
None of these update statements are affecting any change in underlying DB. Is there something I am missing from Gorm usage functionality ?
Try h.db.Exec instead of h.db.Raw.

CT_FETCH error in PowerBuilder Program

I'm still learning PowerBuilder and trying to get familiar with it. I'm receiving the following error when I try to run a program against a specific document in my database:
ct_fetch(): user api layer: internal common library error: The bind of result set item 4 resulted in an overflow. ErrCode: 2.
What does this error mean? What is item 4? This is only when I run this program against a specific document in my database, any other document works fine. Please see code below:
string s_doc_nmbr, s_doc_type, s_pvds_doc_status, s_sql
long l_rtn, l_current_fl, l_apld_fl, l_obj_id
integer l_pvds_obj_id, i_count
IF cbx_1.checked = True THEN
SELECT dsk_obj.obj_usr_num,
dsk_obj.obj_type,
preaward_validation_doc_status.doc_status,
preaward_validation_doc_status.obj_id
INTO :s_doc_nmbr, :s_doc_type, :s_pvds_doc_status, :l_pvds_obj_id
FROM dbo.dsk_obj dsk_obj,
preaward_validation_doc_status
WHERE dsk_obj.obj_id = :gx_l_doc_obj_id
AND preaward_validation_doc_status.obj_id = dsk_obj.obj_id
using SQLCA;
l_rtn = sqlca.uf_sqlerrcheck("w_pdutl095_main", "ue_run_script", TRUE)
IF l_rtn = -1 THEN
RETURN -1
END IF
//check to see if document (via obj_id) exists in the preaward_validation_doc_status table.
SELECT count(*)
into :i_count
FROM preaward_validation_doc_status
where obj_id = :l_pvds_obj_id
USING SQLCA;
IF i_count = 0 THEN
//document doesn't exist
// messagebox("Update Preaward Validation Doc Status", + gx_s_doc_nmbr + ' does not exist in the Preaward Validation Document Status table.', Stopsign!)
//MC - 070815-0030-MC Updating code to insert row into preaward_validation_doc_status if row doesn't already exist
// s_sql = "insert into preaward_validation_doc_status(obj_id, doc_status) values (:gx_l_doc_obj_id, 'SUCCESS') "
INSERT INTO preaward_validation_doc_status(obj_id, doc_status)
VALUES (:gx_l_doc_obj_id, 'SUCCESS')
USING SQLCA;
IF sqlca.sqldbcode <> 0 then
messagebox('SQL ERROR Message',string(sqlca.sqldbcode)+'-'+sqlca.sqlerrtext)
return -1
end if
MessageBox("PreAward Validation ", 'Document number ' + gx_s_doc_nmbr + ' has been inserted and marked as SUCCESS for PreAward Validation.')
return 1
Else
//Update document status in the preaward_validation_doc_status table to SUCCESS
Update preaward_validation_doc_status
Set doc_status = 'SUCCESS'
where obj_id = :l_pvds_obj_id
USING SQLCA;
IF sqlca.sqldbcode <> 0 then
messagebox('SQL ERROR Message',string(sqlca.sqldbcode)+'-'+sqlca.sqlerrtext)
return -1
end if
MessageBox("PreAward Validation ", 'Document number '+ gx_s_doc_nmbr + ' has been marked as SUCCESS for PreAward Validation.')
End IF
update crt_script
set alt_1 = 'Acknowledged' where
ticket_nmbr = :gx_s_ticket_nmbr and
alt_2 = 'Running' and
doc_nmbr = :gx_s_doc_nmbr
USING SQLCA;
Return 1
ElseIF cbx_1.checked = False THEN
messagebox("Update Preaward Validation Doc Status", 'The acknowledgment checkbox must be selected for the script to run successfully. The script will now exit. Please relaunch the script and try again . ', Stopsign!)
Return -1
End IF
Save yourself a ton of headaches and use datawindows... You'd reduce that entire script to about 10 lines of code.
Paul Horan gave you good advice. This would be simple using DataWindows or DataStores. Terry Voth is on the right track for your problem.
In your code, Variable l_pvds_obj_id needs to be the same type as gx_l_doc_obj_id because if you get a result, it will always be equal to it. From the apparent naming scheme it was intended to be long. This is the kind of stuff we look for in peer reviews.
A few other things:
Most of the time you want SQLCode not SQLDbCode but you didn't say what database you're using.
After you UPDATE crt_script you need to check the result.
I don't see COMMIT or ROLLBACK. Autocommit isn't suitable when you need to update multiple tables.
You aren't using most of the values from the first SELECT. Perhaps you've simplified your code for posting or troubleshooting.

Resources