Lets consider a document with an array of embedded documents:
{ _id: 1, arr: [ { fld1: "x", fld2: 43 }, { fld1: "r", fld2: 80 } ] }
I created an index on arr.fld1
; this is a Multikey index (indexes on arrays are called as so). The _id
field already has the default unique index.
The following query uses the indexes on both fields - arr.fld1
and the _id
. The query plan generated using explain()
on the query showed an index scan (IXSCAN) for both fields.
db.test.find( { $or: [ { _id: 2 }, { "arr.fld1": "m" } ] } )
Now the same query filter is used for the update operation also. So, the update where we add two sub-documents to the array:
db.test.update(
{ $or: [ { _id: 1 }, { "arr.fld1": "m" } ] },
{ $addToSet: { arr: { $each: [ { "fld1": "xx" }, { "fld1": "zz" } ] } } }
)
Again, the query plan showed that both the indexes are used for the update operation. Note, I have not used the hint for the find or the update query.
I cannot come to conclusion about what the issue is with your code or indexes (see point Notes: 1, below).
NOTES:
- The above observations are based on queries run on a MongoDB server
version 4.0 (valid for version 3.6 also, as I know).
- The
explain
method is used as follows for find and update:
db.collection.explain().find( ... )
and
db.collection.explain().update( ... )
.
- Note that you cannot generate a query plan using
explain()
for
updateOne
method; it is only available for findAndModify()
and
update()
methods. You can get a list of methods that can generate a
query plan by using the command at mongo shell:
db.collection.explain().help()
.
Note on Java Code:
The Java code to update an array field with multiple sub-document add, is as follows:
collection.updateOne(
or(eq("_id", new Integer(1)), eq("arr.fld1", "m")),
addEachToSet("arr", Arrays.asList(new Document("fld1", "value-1"), new Document("fld1", "value-2"))
);