Skip to content

@MongoId(targetType = STRING) forces _id : {…} query documents to String #3783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
blueiceprj opened this issue Aug 24, 2021 · 6 comments
Closed
Assignees
Labels
type: bug A general bug

Comments

@blueiceprj
Copy link

blueiceprj commented Aug 24, 2021

Spring data version: 3.3.0-M2

I use "_id" field as a string type and I want to use this field with $in operator like this.

@Override
	public List<T> findAllById(Iterable<String> ids)
	{
		final Query query = new Query();
		query.addCriteria(Criteria.where("_id").in(ids));
		return template.find(query, type);
	}

But console output is like this:

find using query: { "_id" : "{\"$in\" : [\"5b8bedceb1e0bfc07b008828\", \"5b8bedceb1e0bfc07b008829\", \"5b8bedceb1e0bfc07b00882a\"]}"} fields: Document{{}} for class:

But $in operator running properly with other fields.

public List<RolePrivilege> findPermissions(String tenantId, List<String> roles)
	{
		final Query query = new Query(Criteria.where("tenantId").is(tenantId));
		if (CollectionUtil.isNotEmpty(roles))
		{
			query.addCriteria(Criteria.where("roleId").in(roles));
		}
		query.addCriteria(notDeletedItemsCriteria);
		return template.find(query, RolePrivilege.class);
	}

find using query: { "tenantId" : "5b8bedceb1e0bfc07b00882f", "roleId" : { "$in" : ["5b8bedceb1e0bfc07b008828", "5b8bedceb1e0bfc07b008829", "5b8bedceb1e0bfc07b00882a", "5b8bedceb1e0bfc07b00882e", "5c6f3b1f1c36570fc572765c", "5eb8b5f540e3006cfa56de26"]}, "deleted" : false} fields: Document{{}} for class

On execution time the criteria api adding backslash "\" to the query and don't return any data.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 24, 2021
@blueiceprj
Copy link
Author

Because of this problem I had to change $in operator to $or.

@mp911de mp911de self-assigned this Aug 30, 2021
@blueiceprj
Copy link
Author

Same result "is" operator when use with Match operator.

String assignmentId = ....
final Criteria assignmentCriteria = Criteria.where("_id").is(assignmentId);
Aggregation.match(assignmentCriteria)

[{ "$match" : { "_id" : { "$oid" : "5f4e7f18fa69b26c3ba619f8"},......]

@mp911de
Copy link
Member

mp911de commented Sep 1, 2021

Thanks for the details. Spring Data MongoDB performs an implicit type conversion to ObjectId when using identifiers that represent a valid ObjectId string. Check out the two variants:

@Document
static class Foo{
	 String id;
}

Query query = new Query();
query.addCriteria(Criteria.where("_id").in(Arrays.asList("5b8bedceb1e0bfc07b008828", "5b8bedceb1e0bfc07b008829", "5b8bedceb1e0bfc07b00882a")));

renders

{"_id": {"$in": [ObjectId("5b8bedceb1e0bfc07b008828"), ObjectId("5b8bedceb1e0bfc07b008829"), ObjectId("5b8bedceb1e0bfc07b00882a")]}}

you can hint Spring Data to use a specific Id field type with @MongoId (defaults to retain the actual type):

@Document
static class Foo{
	 @MongoId
	 String id;
}

Query query = new Query();
query.addCriteria(Criteria.where("_id").in(Arrays.asList("5b8bedceb1e0bfc07b008828", "5b8bedceb1e0bfc07b008829", "5b8bedceb1e0bfc07b00882a")));

renders

{"_id": {"$in": ["5b8bedceb1e0bfc07b008828", "5b8bedceb1e0bfc07b008829", "5b8bedceb1e0bfc07b00882a"]}}

Note that the Mongo query is rendered using Mongo shell settings.

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Sep 1, 2021
@blueiceprj
Copy link
Author

Thank you for your reply. Id description like here on my side:

	@MongoId(targetType = FieldType.STRING)
	private String id;

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Sep 1, 2021
@blueiceprj
Copy link
Author

And sometimes I use custom data object (DTO) to mapping. Its not a mongodb document object and it has id field. But on custom object as same problem.

@mp911de
Copy link
Member

mp911de commented Sep 1, 2021

Thanks a lot. What happens is that the $in clause is being converted to a String. It should been preserved as Document. You can see this through the escaped quotes {\"$in\" : [\"5b8bedceb1e0bfc07b008828\", \"5b8bedceb1e0bfc07b008829\".

@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Sep 1, 2021
@mp911de mp911de changed the title $in criteria problem @MongoId(targetType = STRING) forces _id : {…} query documents to String Sep 1, 2021
christophstrobl pushed a commit that referenced this issue Sep 2, 2021
…n explicit write target.

We now no longer attempt to convert query Documents into primitive types to avoid e.g. Document to String conversion.

Closes: #3783
Original Pull Request: #3797
christophstrobl pushed a commit that referenced this issue Sep 2, 2021
…n explicit write target.

We now no longer attempt to convert query Documents into primitive types to avoid e.g. Document to String conversion.

Closes: #3783
Original Pull Request: #3797
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
3 participants