Search code examples
regexmongodbgomgo

Translate specific return query into mgo


I have a query which returns all names from a collection's documents which contain a specific text. In the following example, return all names which contain the sequence "oh" case-insensitively; do not return other fields in the document:

find({name:/oh/i}, {name:1, _id:0})

I have tried to translate this query into mgo:

Find([]bson.M{bson.M{"name": "/oh/i"}, bson.M{"name": "1", "_id": "0"}})

but there are always zero results when using mgo. What is the correct syntax for such a query using mgo?

This question is different from the alleged duplicates because none of those questions deal with how to restrict MongoDB to return only a specific field instead of entire documents.


Solution

  • To execute queries that use regexp patterns for filtering, use the bson.RegEx type.

    And to exclude fields from the result documents, use the Query.Select() method.

    Like in this example:

    c.Find(bson.M{"name": bson.RegEx{Pattern: "oh", Options: "i"}}).
        Select(bson.M{"name": 1, "_id": 0})
    

    Translation of the regexp:

    name:/oh/i
    

    This means to match documents where the name field has a value that contains the "oh" sub-string, case insensitive. This can be represented using a bson.RegEx, where the RegEx.Pattern field gets the pattern used in the above expression ("oh"). And the RegEx.Options may contain options now to apply / match the pattern. The doc lists the possible values. If the Options field contains the 'i' character, that means to match case insensitive.

    If you have a user-entered term such as "[a-c]", you have to quote regexp meta characters, so the final pattern you apply should be "\[a-c\]" To do that easily, use the regexp.QuoteMeta() function, e.g.

    fmt.Println(regexp.QuoteMeta("[a-c]")) // Prints: \[a-c\]
    

    Try it on the Go Playground.