Skip to content

Commit 0273e5b

Browse files
committed
Merge pull request #77 from nitram509/issue-76
FIX: issue #76 (Querying indexed field in subdocument does not work, but works without index)
2 parents 8ec4c99 + 2628973 commit 0273e5b

File tree

2 files changed

+60
-34
lines changed

2 files changed

+60
-34
lines changed

src/main/java/com/github/fakemongo/impl/index/IndexAbstract.java

+32-34
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,14 @@
33
import com.github.fakemongo.impl.ExpressionParser;
44
import com.github.fakemongo.impl.Filter;
55
import com.github.fakemongo.impl.Util;
6+
import com.mongodb.BasicDBList;
67
import com.mongodb.DBObject;
78
import com.mongodb.FongoDBCollection;
89
import com.mongodb.MongoException;
9-
import java.util.ArrayList;
10-
import java.util.Collection;
11-
import java.util.Collections;
12-
import java.util.List;
13-
import java.util.Map;
14-
import java.util.Set;
1510
import org.bson.types.Binary;
1611

12+
import java.util.*;
13+
1714
/**
1815
* An index for the MongoDB.
1916
* <p/>
@@ -263,42 +260,43 @@ public void clear() {
263260
* @return true if index can be used.
264261
*/
265262
public boolean canHandle(final DBObject queryFields) {
266-
if(queryFields == null) {
267-
return false;
268-
}
263+
if (queryFields == null) {
264+
return false;
265+
}
269266

270-
//get keys including embedded indexes
271-
for (String field : fields) {
272-
if (!queryFields.containsField(field) && !keyEmbeddedFieldMatch(field, queryFields)) {
273-
return false;
274-
}
267+
//get keys including embedded indexes
268+
for (String field : fields) {
269+
if (!queryFields.containsField(field) && !keyEmbeddedFieldMatch(field, queryFields)) {
270+
return false;
275271
}
272+
}
276273
return true;
277-
// return queryFields.containsAll(fields);
278274
}
279275

280-
public boolean keyEmbeddedFieldMatch(String field, DBObject queryFields)
281-
{
282-
//if field embedded field type
283-
String[] fieldParts = field.split("\\.");
284-
if(fieldParts.length == 0) {
285-
return false;
286-
}
287-
288-
DBObject searchQueryFields = queryFields;
289-
int count = 0;
290-
for(String fieldPart : fieldParts) {
291-
count++;
292-
if(!searchQueryFields.containsField(fieldPart)) {
293-
return false;
294-
} else if (searchQueryFields.get(fieldPart) instanceof DBObject) {
295-
searchQueryFields = (DBObject)searchQueryFields.get(fieldPart);
296-
}
297-
}
276+
private boolean keyEmbeddedFieldMatch(String field, DBObject queryFields) {
277+
//if field embedded field type
278+
String[] fieldParts = field.split("\\.");
279+
if (fieldParts.length == 0) {
280+
return false;
281+
}
298282

299-
return fieldParts.length == count;
283+
DBObject searchQueryFields = queryFields;
284+
int count = 0;
285+
for (String fieldPart : fieldParts) {
286+
count++;
287+
if (searchQueryFields instanceof BasicDBList) {
288+
// when it's a list, there's no need to investigate nested documents
289+
return true;
290+
} else if (!searchQueryFields.containsField(fieldPart)) {
291+
return false;
292+
} else if (searchQueryFields.get(fieldPart) instanceof DBObject) {
293+
searchQueryFields = (DBObject) searchQueryFields.get(fieldPart);
294+
}
300295
}
301296

297+
return fieldParts.length == count;
298+
}
299+
302300
@Override
303301
public String toString() {
304302
return "Index{" +

src/test/java/com/github/fakemongo/FongoTest.java

+28
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,34 @@ public void testFindOneIn() {
174174
assertEquals(new BasicDBObject("date", 1), result);
175175
}
176176

177+
/**
178+
* @see <a href="https://github.com/fakemongo/fongo/issues/76">
179+
* Querying indexed field in subdocument does not work, but works without index
180+
* </a>
181+
*/
182+
@Test
183+
public void testFindOneIn_within_array_and_given_index_set() {
184+
DBCollection collection = newCollection();
185+
// prepare documents
186+
collection.insert(
187+
new BasicDBObject("_id", 1)
188+
.append("animals", new BasicDBObject[]{
189+
new BasicDBObject("name", "dolphin").append("type", "mammal"),
190+
}),
191+
new BasicDBObject("_id", 2)
192+
.append("animals", new BasicDBObject[]{
193+
new BasicDBObject("name", "horse").append("type", "mammal"),
194+
new BasicDBObject("name", "shark").append("type", "fish")
195+
}));
196+
// prepare index
197+
collection.createIndex(new BasicDBObject("animals.type", "text"));
198+
199+
DBObject result = collection.findOne(new BasicDBObject("animals.type", new BasicDBObject("$in", new String[]{"fish"})));
200+
201+
assertNotNull(result);
202+
assertEquals(2, result.get("_id"));
203+
}
204+
177205
@Test
178206
public void testFindOneInWithArray() {
179207
DBCollection collection = newCollection();

0 commit comments

Comments
 (0)