0
votes

I am trying to find whether a field exist in a nested document using Go.

Currently, the document looks like this. enter image description here

I am trying to see if the item id field- 5f15d53f205c36fa8b022089 exist in the shoppingCart for this user. Using the Mongo Compass, I am able to successfully query the right document using this filter command.

{"_id": ObjectId('5f19a8950268ef67ce0c5124'), "shoppingCart.items.5f15d53f205c36fa8b022089": {$exists: true}} 

I tried to do use the same syntax in Go, but I still get nothing back from the results.

cursor, err := customersCollection.Find(
        ctx,
        bson.M{"_id": customerID, "shoppingCart.items.5f15d53f205c36fa8b022089": bson.M{"$exists": true}},
        options.Find().SetProjection(bson.M{"_id": 1}),
    ) 
    // This is how I am reading the results from the cursor. When
    // printing the results, I get an empty array.
    var results []bson.M
    if err = cursor.All(ctx, &results); err != nil {
        customerLog.Errorf(logger.LogError(logger.LogInfo()), err)
    }

    fmt.Printf("Products Result: %v\n", results)

I am unable to find any documentation for the proper way to include element query operators in the filter parameter.

This is the Mongo driver I am using, https://godoc.org/go.mongodb.org/mongo-driver/mongo

Edit 1.0 Things that I have tried:

  • Used bson.D instead of bson.M. Updated code segment.

    cursor, err := customersCollection.Find( ctx, bson.D{{"_id", customerID}, {"shoppingCart.items.5f15d53f205c36fa8b022089", bson.D{{"$exists", true}}}}, options.Find().SetProjection(bson.M{"_id": 1}), )

2
If the driver implements command monitoring, enable that to see what queries are being generated/sent. - D. SM
What is the type of customerID you are passing in query? - Burak Serdar
the customerID type is primitive.ObjectID. I know the customerID works because I tested with just the customerID, and it returns the right the document. It stops working once I add the shoppingCart.items query - cruise_lab
You query syntax looks ok. I would try using a different field to see if $exists is the problem, like try it with phone field. - Burak Serdar
@BurakSerdar phone field works for me? So is there something different for nested documents? - cruise_lab

2 Answers

2
votes

if you use go.mongodb.org/mongo-driver/bson package, you can do the following:

query := bson.M{}
query["_id"] = bson.M{
    "$exists": true,
}

If you want, you can also do it cleaner, by using a wrapper:

type FilterQuery bson.M

func NewFilterQuery() FilterQuery {
    return FilterQuery(bson.M{})
}

func (q FilterQuery) SetIdExists(exist bool) FilterQuery {
    q["_id"] = bson.M{
        "$exists": exist,
    }
    return q
}

And then from your code, you can do something like

query := NewFilterQuery()
query.SetIdExist(true)
..
cursor, err := customersCollection.Find(
        ctx,
        query,
    ) 
...

0
votes

Try the following:

bson.D{
   {"$exists", true},
}

(I searched the driver's source for $exist.)