Good morning,
I´m trying to combine regular expression with Spring data mongodb repository using Query annotation.
What I want is search one substring inside one string attribute of my mongo document.
I have been looking in google and here, but I did not find anything elegant, and I was wondering if Spring data has something official about this using the repositories.
Regards.
It seems like an old question, so maybe you've already had a solution but here how I handled the same issue :
#Query(value = "{'title': {$regex : ?0, $options: 'i'}}")
Foo findByTitleRegex(String regexString);
using the /?0/ notation won't work since Spring Data places a String value with quotes
Related
I am struggling with a mongo query. I need to find a collection of documents in single query. The collection should contain document with newest date (field createdAt) for every user in single query.
There is a test case in Spock to demonstrate what I am trying to acheive:
def 'should filter the newest location for every user'() {
given:
List locationsInDb = [
buildLocation(USERNAME_1, '2017-02-03T10:37:30.00Z'),
buildLocation(USERNAME_1, '2017-03-04T10:37:30.00Z'),
buildLocation(USERNAME_2, '2017-02-05T10:37:30.00Z'),
buildLocation(USERNAME_2, '2017-03-06T10:37:30.00Z')
]
insertToMongo(locationsInDb)
when:
List filteredLocations = locationRepository.findLastForEveryUser()
then:
filteredLocations == [locationsInDb.get(1), locationsInDb.get(3)]
}
I found that distinct methods are a part of 2.1.0.M1 version so they are not available yet.
I was also trying with #Query annotation but the documentation (link below) does not specify how to create a query like mine.
https://docs.spring.io/spring-data/data-document/docs/current/reference/html/#d0e3309
Thanks for your help.
There are no means to express the query you are looking for via a derived query in Spring Data, nor using the MongoDB native query operators. Distinct as well will not do the job as it just extracts distinct values of a single field into an array.
Please consider using an Aggregation. Spring Data specifics can be found in the reference documentation.
I have a MongoDB collection containing User objects with two fields: Firstname and Lastname. I need a query that takes only one string (representing the user fullname) for a findLike research.
The problem is the same of this question but I do not know how translate that query for a MongoDB Repository in Spring Data using MongoTemplate or #Query annotation
EDIT:
Using project operator i have to specify all fields I want include in the stages. A better solution maybe could be use AddFields operator:
A similar question I found is that:
https://stackoverflow.com/a/40812293/6545142
How can I use the $AddFields operator with MongoTemplate?
You can use $expr ( 3.6 mongo version operator ) to use aggregation functions in regular query for only exact matches.
Spring #Query code
#Query("{$expr:{$eq:[{$concat:["$Firstname","$Lastname"]}, ?0]}}")
ReturnType MethodName(ArgType arg);
For find like searches or exact search you've to use aggregation via mongo template in lower versions.
AggregationOperation project = Aggregation.project().and(StringOperators.Concat.valueOf("Firstname").concatValueOf("Lastname")).as("newField");
for like matches
AggregationOperation match = Aggregation.match(Criteria.where("newField").regex(val));
for exact match
AggregationOperation match = Aggregation.match(Criteria.where("newField").is(val));
Rest of the code
Aggregation aggregation = Aggregation.newAggregation(project, match);
List<BasicDBObject> basicDBObject = mongoTemplate.aggregate(aggregation, colname, BasicDBObject.class).getMappedResults();
We are using the spring-data-elasticsearch project to interface with our elasticsearch clusters, and have been using it now for around a year. Recently, we moved to elasticsearch 5.x (from 2.x) where we now have the "keyword" datatype.
I would like to index these keywords as lowercase values, which I know can be done with field normalizers. I can't find anywhere in the documentation or online where I can add a normalizer to a field through the annotation based mapping.
E.g
#Field(type = FieldType.keyword, <some_other_param = some_normalizer>)
Is this something that can be done? I know that we can use JSON based mapping definitions as well, so I will fall back to that option if needed, but would like to be able to do it this way if possible.
Any help would be very appreciated!
Since the pull request of #xhaggi has been merged (spring-data-elasticsearch 3.1.3+ or Spring Boot 2.1.1), we have a normalizer field in the #Field annotation.
To use it, we need:
declare a #Field or an #InnerField with params type = FieldType.Keyword, normalizer = "%NORMALIZER_NAME%"
add #Setting(settingPath = "%PATH_TO_NORMALIZER_JSON_FILE%") at the class level.
put the normalizer mapping into a json file at %PATH_TO_NORMALIZER_JSON_FILE%
Example of usage
FYI, for anyone looking at this, the answer is there is not a way to do this at this time.
You can do this, however, by creating your mappings file as JSON in the Elasticsearch format. See:
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html
You can then create that JSON file and link it to your Domain model with.
#Mapping(mappingPath = "some/path/mapping.json")
Note that this is not, in my experience, compatible with the provided annotation based mapping for fields.
There is a pending issue https://jira.spring.io/browse/DATAES-492 waiting for review.
I am new to Jackson DB. Now I know that to get the entire document list of a collection using Jackson we need to do :
COllectionClass.coll.find().toArray();
which is Jackson DB equivalent to the mongodb command :
db.collection.find()
So What is the Jackson DB equivalent of say :
db.collection.find({},{"fieldName":1, "_id":0})
As given here, This might be helpful to you. (not tested)
coll.find(DBQuery.is(),//add your criteria for search here
DBProjection.include("fieldName")).toArray();
I wonder if there's any mechanism to use count in Spring Data MongoDB repository with #Query annotation?
I would love to receive the number of documents that I have without having to get all of them.
Basically, the equivalent of this in Java:
db.test.find({"type":"foo"}).count
Another way to do this using MongoRepository query templates:
public interface MyRepository extends MongoRepository<MyClass, String> {
Long countByLastname(String lastname);
}
See http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories.query-methods.details
For me this solutions works like a charm( using spring-data-mongodb 1.3.1.RELEASE ),
I just had the same problem atm and solved it like this(just a short snippet from my code at work):
#Query(value = "{'productDetails.productType': {$regex: ?0, $options: 'i'}, 'sourceDescriptor': ?1}", count = true)
public Long countFetchedDocumentsForCategory(String cat, String sourceDescriptor);
I had same problem recently and unfortunately did not find any solution at least not with current stable version. It seems that it is possible in Spring Data JPA 1.4M1 so maybe it will be also included in next version of Spring Data MongoDB.