How to construct an $or query in mgo - go

I am trying to convert this JS MongoDB query into Go mgo query:
var foo = "bar";
db.collection.find({"$or": [ {uuid: foo}, {name: foo} ] });
This is what I've got so far, but it doesn't work:
conditions := bson.M{"$or": []bson.M{bson.M{"uuid": name}, bson.M{"name": name}}}
EDIT: It does seem to work now. Maybe I had a typo somewhere.

Here is a complete example which works fine for me (with Go 1.4, and MongoDB 2.6.5)
package main
import (
"fmt"
"log"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
type Person struct {
Num int
Uuid string
Name string
}
func main() {
// Connect to the database
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
// Remove people collection if any
c := session.DB("test").C("people")
c.DropCollection()
// Add some data
err = c.Insert(&Person{ 1, "UUID1", "Joe"},
&Person{ 2, "UUID2", "Jane"},
&Person{ 3, "UUID3", "Didier" })
if err != nil {
log.Fatal(err)
}
result := Person{}
err = c.Find( bson.M{ "$or": []bson.M{ bson.M{"uuid":"UUID0"}, bson.M{"name": "Joe"} } } ).One(&result)
if err != nil {
log.Fatal(err)
}
fmt.Println(result)
}

package main
import (
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func GetAll()[]interface{}{
//Data Base Instance
session, err := mgo.Dial("localhost")
c := session.DB("yourDbName").C("YourCollectionName")
foo := "bar"
orQuery := []bson.M{}
uidFindQuery := bson.M{uuid: foo}
nameFindQuery := bson.M{name: foo}
orQuery = append(orQuery, uidFindQuery, nameFindQuery)
result := []interface{}{}
err := c.Find(bson.M{"$or":orQuery}).All(&result);
fmt.Println("error", err)
fmt.Println("Your expected Data",result)
return result
} `
Reference
https://gopkg.in/mgo.v2 Best Mongo db interface for go lang

Related

RethinkDB r.DBList() gives blank object in return

I'm using this golang code to check list of databases in RethinkDB, and getting no lists in return.
package main
import (
"encoding/json"
"fmt"
"log"
r "gopkg.in/rethinkdb/rethinkdb-go.v6"
)
func main() {
log.SetFlags(0)
rdbOpts := r.ConnectOpts{
Address: "localhost:28015",
}
rconn, err := r.Connect(rdbOpts)
checkError(err)
res, err := r.DBList().Run(rconn)
checkError(err)
printObj(res)
}
func checkError(err error) {
if err != nil {
log.Println(err)
return
}
}
func printObj(v interface{}) {
vBytes, _ := json.Marshal(v)
fmt.Println(string(vBytes))
}
Result:
$ go run main.go
{}
This is just a fresh started Rethinkdb instance on local machine, which if queried through Data Explorer from web ui indeed returns the following answer for query r.dbList()
[
"rethinkdb" ,
"test"
]
What am I doing wrong in my query? I know it must be something small, as it's just basic query.
Appreciate any pointers or help. Thanks
I see what I was doing wrong. 🤦‍♂️
I didn't process the response to show rows data as per RethinkDb docs.
Here's the working main() func code:
func main() {
rdbOpts := r.ConnectOpts{
Address: "localhost:28015",
}
rconn, err := r.Connect(rdbOpts)
checkError(err)
res, err := r.DBList().Run(rconn)
checkError(err)
printObj(res)
var row []interface{}
err2 := res.All(&row)
if err2 == r.ErrEmptyResult {
// row not found
}
if err2 != nil {
// error
}
if row != nil {
jsonData, _ := json.Marshal(row)
fmt.Println("total number of rows:", len(row))
fmt.Println("row map obj:", row)
fmt.Println("row JSON output:", string(jsonData))
} else {
fmt.Println("No rows returned")
}
}
Output:
$ go run main.go
{}
total number of rows: 2
row map obj: [rethinkdb test]
row JSON output: ["rethinkdb","test"]

Go elasticsearch bulk insert

I have been unable to solve the problem into elasticsearch Bulk method for several days, since I am not strong in Go and started learning it not so long ago, while executing the code :
package main
import (
"bytes"
json "encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
)
type BulkInsertMetaData struct {
Index []BulkInsertIndex `json:"index"`
}
type BulkInsertIndex struct {
Index string `json:"_index"`
ID string `json:"_id"`
}
type BulInsertData struct {
Url string `json:"url"`
}
func main() {
dataMeta := BulkInsertMetaData{
Index: []BulkInsertIndex{
{
Index: "Test",
ID: "1234567890",
},
},
}
data := BulInsertData{
Url: "http://XXXX.XX",
}
TojsBulInsertData, _ := json.Marshal(data)
TojsBulkInsertMetaData, _ := json.Marshal(dataMeta)
BulkMetaData := bytes.NewBuffer(append(TojsBulkInsertMetaData, []byte("\n")...))
BulkData := bytes.NewBuffer(append(TojsBulInsertData, []byte("\n")...))
log.Println(BulkMetaData)
log.Println(BulkData)
respMetaData, err := http.Post("http://127.0.0.1:9200/_bulk", "application/json", BulkMetaData)
if err != nil {
log.Println(err)
}
body, err := ioutil.ReadAll(respMetaData.Body)
if err != nil {
log.Println(err)
}
fmt.Println(string(body))
respBulkData, err := http.Post("http://127.0.0.1:9200/_bulk", "application/json", BulkData)
if err != nil {
log.Println(err)
}
body2, err := ioutil.ReadAll(respBulkData.Body)
if err != nil {
log.Println(err)
}
fmt.Println(string(body2))
}
but i get an error:
2022/02/09 14:37:02 {"index":[{"_index":"Test","_id":"1234567890"}]}
2022/02/09 14:37:02 {"url":"http://XXXX.XX"}
{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"Malformed action/metadata line [1], expected START_OBJECT or END_OBJECT but found [START_ARRAY]"}],"type":"illegal_argument_exception","reason":"Malformed action/metadata line [1], expected START_OBJECT or END_OBJECT but found [START_ARRAY]"},"status":400}
please help and explain what I'm doing wrong, I searched the Internet for the answer to my question but did not find
I test insert when using REST client passes without problems
BulkMetaData should be {"index":{"_index":"Test","_id":"1234567890"}} (without []) and it should be sent to /_bulk together with BulkData, as a single payload:
{"index":{"_index":"Test","_id":"1234567890"}}
{"url":"http://XXXX.XX"}
Sorry for kinda necroing but I also recently needed to design a Bulk connector in our codebase and the fact that there are NO NDJSON encoder/decoders out on the web is appalling. Here is my implementation:
func ParseToNDJson(data []map[string]interface{}, dst *bytes.Buffer) error {
enc := json.NewEncoder(dst)
for _, element := range data {
if err := enc.Encode(element); err != nil {
if err != io.EOF {
return fmt.Errorf("failed to parse NDJSON: %v", err)
}
break
}
}
return nil
}
Driver code to test:
func main() {
var b bytes.Buffer
var data []map[string]interface{}
// pointless data generation...
for i, name := range []string{"greg", "sergey", "alex"} {
data = append(data, map[string]interface{}{name: i})
}
if err := ParseToNDJson(query, &body); err != nil {
return nil, fmt.Errorf("error encoding request: %s", err)
}
res, err := esapi.BulkRequest{
Index: "tasks",
Body: strings.NewReader(body.String()),
}.Do(ctx, q.es)
Hope this helps someone

Get permanent MAC address

Is there an easy way to get the permanent MAC Address using Go?
package main
import (
"fmt"
"log"
"net"
)
func getMacAddr() ([]string, error) {
ifas, err := net.Interfaces()
if err != nil {
return nil, err
}
var as []string
for _, ifa := range ifas {
a := ifa.HardwareAddr.String()
if a != "" {
as = append(as, a)
}
}
return as, nil
}
func main() {
as, err := getMacAddr()
if err != nil {
log.Fatal(err)
}
for _, a := range as {
fmt.Println(a)
}
}

Text/template: "can't call method/function with 0 results."

How can I execute function in templates that returns no value? Here is example:
func main() {
u, err := url.Parse("http://example.com/test?param1=true&param2=true")
if err != nil {
log.Fatal(err)
}
m := u.Query()
m.Del("param1") // param1 successful deleted!
u.RawQuery = m.Encode()
fmt.Println(u.RawQuery)
const tmpl = `
{{$m := .Query}}
{{$m.Del "param2"}} <!-- failed to delete param2! -->
{{.RawQuery}}
`
t := template.Must(template.New("").Parse(tmpl))
err = t.Execute(os.Stdout, u)
if err != nil {
log.Println("executing template:", err)
}
}
see this code in play.golang.org
I know that in templates shouldn't be much logic, but ignorance of running function that returns no value seems to me interesting issue.
Templates in Go are not like those in other languages (e.g. PHP). Use template.FuncMap to create custom functions for your templates.
package main
import (
"fmt"
"log"
"net/url"
"os"
"text/template"
)
func main() {
funcMap := template.FuncMap{
"delete": deleteMap,
}
u, err := url.Parse("http://example.com/test?param1=true&param2=true")
if err != nil {
log.Fatal(err)
}
u = deleteMap(u, "param1") // works in regular code and templates
fmt.Println(u.RawQuery)
const tmpl = `
{{$m := delete . "param2"}} <!-- WORKS! -->
{{$m.RawQuery}}
`
t := template.New("").Funcs(funcMap)
t = template.Must(t.Parse(tmpl))
err = t.Execute(os.Stdout, u)
if err != nil {
log.Println("executing template:", err)
}
}
func deleteMap(u *url.URL, key string) *url.URL {
m := u.Query()
m.Del(key) // key successful deleted!
u.RawQuery = m.Encode()
return u
}
Or, try the playground version.

Go template to struct

I have a Go template that should resolve to a struct. How can I convert the bytes.Bufferresult from template execute function back to the struct. Playground
package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
"text/template"
)
type Data struct {
Age int
Username string
SubData SubData
}
type SubData struct {
Name string
}
func main() {
s := SubData{Name: "J. Jr"}
d := Data{Age: 26, Username: "HelloWorld", SubData: s}
tmpl := "{{ .SubData }}"
t := template.New("My template")
t, _ = t.Parse(string(tmpl))
buffer := new(bytes.Buffer)
t.Execute(buffer, d)
fmt.Println(buffer)
// writing
enc := gob.NewEncoder(buffer)
err := enc.Encode(s)
if err != nil {
log.Fatal("encode error:", err)
}
// reading
buffer = bytes.NewBuffer(buffer.Bytes())
e := new(SubData)
dec := gob.NewDecoder(buffer)
err = dec.Decode(e)
if err != nil {
log.Fatal("decode error:", err)
}
fmt.Println(e, err)
}
You cannot. This is plain simply impossible.
But why on earth would anybody want to do something like this? Why don't you just send your Data directly via gob and decode it directly? Why creating a textual representation which you gob?

Resources