Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 141eccb

Browse files
Dragomir-Ivanovsmyrman
authored andcommitted
Implements $elemMatch query operator. Due to rs/rest-layer #237.
1 parent fdfdf52 commit 141eccb

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

mongo_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,12 @@ func TestFind(t *testing.T) {
425425
{ID: "3", Payload: map[string]interface{}{"id": "3", "name": "c", "age": 3}},
426426
{ID: "4", Payload: map[string]interface{}{"id": "4", "name": "d", "age": 4}},
427427
{ID: "5", Payload: map[string]interface{}{"id": "5", "name": "rest-layer-regexp"}},
428+
{ID: "6", Payload: map[string]interface{}{"id": "6", "name": "f",
429+
"arr": []interface{}{
430+
map[string]interface{}{"a": "foo", "b": "bar"},
431+
map[string]interface{}{"a": "foo", "b": "baz"},
432+
},
433+
}},
428434
}
429435
doPositiveFindTest := func(t *testing.T, h mongo.Handler, q *query.Query) *resource.ItemList {
430436
l, err := h.Find(context.Background(), q)
@@ -608,4 +614,21 @@ func TestFind(t *testing.T) {
608614
}
609615
t.Run("then ItemList.Items should include all matching items", itemsCheckFunc(expectItems, l))
610616
})
617+
t.Run("when quering for array of objects match", func(t *testing.T) {
618+
l := doPositiveFindTest(t, h, &query.Query{
619+
Predicate: query.MustParsePredicate(`{arr:{$elemMatch:{a:"foo"}}}`),
620+
})
621+
622+
t.Run("then ItemList.Total should be deduced correctly", totalCheckFunc(1, l))
623+
624+
expectItems := []*resource.Item{
625+
{ID: "6", ETag: "p-6", Payload: map[string]interface{}{"id": "6", "name": "f",
626+
"arr": []interface{}{
627+
map[string]interface{}{"a": "foo", "b": "bar"},
628+
map[string]interface{}{"a": "foo", "b": "baz"},
629+
},
630+
}},
631+
}
632+
t.Run("then ItemList.Items should include the first matching item", itemsCheckFunc(expectItems, l))
633+
})
611634
}

query.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ func translatePredicate(q query.Predicate) (bson.M, error) {
8888
s = append(s, sb)
8989
}
9090
b["$or"] = s
91+
case *query.ElemMatch:
92+
s := bson.M{}
93+
for _, subExp := range t.Exps {
94+
sb, err := translatePredicate(query.Predicate{subExp})
95+
if err != nil {
96+
return nil, err
97+
}
98+
for k, v := range sb {
99+
s[k] = v
100+
}
101+
}
102+
b[getField(t.Field)] = bson.M{"$elemMatch": s}
91103
case *query.In:
92104
b[getField(t.Field)] = bson.M{"$in": t.Values}
93105
case *query.NotIn:

query_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func TestTranslatePredicate(t *testing.T) {
4444
{`{f:{$regex:"fo[o]{1}.+is.+some"}}`, nil, bson.M{"f": bson.M{"$regex": "fo[o]{1}.+is.+some"}}},
4545
{`{$and:[{f:"foo"},{f:"bar"}]}`, nil, bson.M{"$and": []bson.M{bson.M{"f": "foo"}, bson.M{"f": "bar"}}}},
4646
{`{$or:[{f:"foo"},{f:"bar"}]}`, nil, bson.M{"$or": []bson.M{bson.M{"f": "foo"}, bson.M{"f": "bar"}}}},
47+
{`{f:{$elemMatch:{a:"foo",b:"bar"}}}`, nil, bson.M{"f": bson.M{"$elemMatch": bson.M{"a": "foo", "b": "bar"}}}},
4748
}
4849
for i := range cases {
4950
tc := cases[i]

0 commit comments

Comments
 (0)