4

I'm trying to query my mongodb database using golang (and the mgo library) with only one function, and the method I am currently using is:

er = c.Find(sel(items)).Sort("-createdAt").All(&result)

Where items is a map and the key is the name of the field I am searching inthe db, and the value is what I want to search by.

and sel() is:

func sel(query map[string]string) bson.M {
result := make(bson.M, len(query))
result[ ] = "$in"
for k, v := range query {
    result[k] = v
}
return result

currently it will return all of the results where at least one of the fields matches the input map. (So a logical OR) however I would like it to return the logical AND of these fields.

Does anyone have suggestions on how to modify the existing code or a new way of efficiently querying the database?

Thank you

3
  • Can you elaborate the logical AND behavior you desire? Matching all the fields, not any of them? Commented Jun 27, 2018 at 18:48
  • 1
    I am hoping to get a result where each value in the map matches the corresponding field in the database. So I would like it to be something like bson.M{"$and" : all of the k,v pairs} Commented Jun 27, 2018 at 18:52
  • So yes, matching all of the fields Commented Jun 27, 2018 at 18:54

1 Answer 1

4

I don't know what this line is supposed to mean:

result[ ] = "$in"

As it is a compile-time error.

But the elements of the query document (the conditions) are in logical AND connection by default, so this is all it takes:

func sel(query map[string]string) bson.M {
    result := make(bson.M, len(query))
    for k, v := range query {
        result[k] = v
    }
    return result
}

If this gives you all the documents in the collection, then that means all the key-value pairs match all the documents. Experiment with simple filters to see that it works.

Also note that the mgo package also accepts a wide range of maps and structs, not just bson.M. Documentation of Collection.Find() has this to say about the allowed types:

The document may be a map or a struct value capable of being marshalled with bson. The map may be a generic one using interface{} for its key and/or values, such as bson.M, or it may be a properly typed map. Providing nil as the document is equivalent to providing an empty document such as bson.M{}.

So you can use your map which is of type map[string]string without converting it:

err = c.Find(items).Sort("-createdAt").All(&result)
Sign up to request clarification or add additional context in comments.

4 Comments

I forgot to remove that line before copying! Thank you. Also we just found a bug in the code from a colleague of mine that was causing our "query" problem that turns out wasn't even a db issue... Gotta love human error
@bagreeni Please see my edit. You don't even need this sel() conversion: you can just use your original map[string]string map without conversion!
Thank you! This is extremely helpful to know
@bagreeni I provided exact description (with reference) about what can be used as the query.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.