I am using spring and mongo for API developemt with the following document structure:
Document-1
myId:1
array:['abc','jkl','xyz']
Document-2
myId:3
array:['qwe','mnp','xyz']
Document-3
myId:3
array:['ped','abc','xyz']
My url : localhost:8080/array=xyz
expected : document-1,document-2,document-3
My url: localhost:8080/array=xyz,abc
exoected: document-1,document-3
In short I want all the documents in result which contains all the comma separated array
variable.
Is there ary inbuild support that spring provides for this like @Query annotation?
Or How can I acheive this?
To search the array of object in MongoDB, you can use $elemMatch operator. This operator allows us to search for more than one component from an array object.
One of the benefits of MongoDB's rich schema model is the ability to store arrays as document field values. Storing arrays as field values allows you to model one-to-many or many-to-many relationships in a single document, instead of across separate collections as you might in a relational database.
ArrayList<String> stringArray = new ArrayList<String>(); BasicDBObject document = new BasicDBObject(); document. put("master", stringArray); db. getCollection("master"). insert(document);
If the field is absent in the document to update, $push adds the array field with the value as its element. If the field is not an array, the operation will fail. If the value is an array, $push appends the whole array as a single element. To add each element of the value separately, use the $each modifier with $push .
You essentially want to use the $all
operator to get the desired results. In the mongo shell, the following operation will bring the documents:
Populate test collection
db.test.insert([
{
_id: 1,
myId: 1,
array: ['abc','jkl','xyz']
},
{
_id: 2,
myId: 3,
array: ['qwe','mnp','xyz']
},
{
_id: 3,
myId: 3,
array:['ped','abc','xyz']
}
])
Run operations
> db.test.find({"array": { "$all": ["xyz"] }})
{ "_id" : 1, "myId" : 1, "array" : [ "abc", "jkl", "xyz" ] }
{ "_id" : 2, "myId" : 3, "array" : [ "qwe", "mnp", "xyz" ] }
{ "_id" : 3, "myId" : 3, "array" : [ "ped", "abc", "xyz" ] }
> db.test.find({"array": { "$all": ["abc", "xyz"] }})
{ "_id" : 1, "myId" : 1, "array" : [ "abc", "jkl", "xyz" ] }
{ "_id" : 3, "myId" : 3, "array" : [ "ped", "abc", "xyz" ] }
As with the @Query
annotation in Spring Data MongoDB, I haven't tested this but you may want to try the following custom query implementation example
@Document(collection="test")
class Test {
int myId;
String[] array;
}
public interface TestRepository extends MongoRepository<Test, Integer> {
@Query(value = "{ 'array' : {$all : [?0] }}")
public List<Test> findAnyOfTheseValues(String[] arrayValues);
}
If the above doesn't work for you, you may want to create a custom interface and your implementation class to execute the custom query. For example, create an interface with a name that appends Custom:
public interface TestRepositoryCustom {
public List<Test> findAnyOfTheseValues(String[] arrayValues);
}
Modify the TestRepository
and add the TestRepositoryCustom
interface to be extended:
@Repository
public interface TestRepository extends TestRepositoryCustom, MongoRepository {
}
Create your implementation class to implement the methods defined in TestRepositoryCustom
interface.
public class TestRepositoryImpl implements TestRepositoryCustom {
@Autowired
MongoTemplate mongoTemplate;
@Override
public List<Test> findAnyOfTheseValues(String[] arrayValues) {
return mongoTemplate.find(
Query.query(Criteria.where("array").all(arrayValues)), Test.class);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With