Skip to content
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

new implementation of $elemMatch support #985

Merged
merged 6 commits into from
Sep 7, 2016
Merged

Conversation

evanchooly
Copy link
Member

This is a replacement implementation of $elemMatch. The old "hasThisElement" and "doesNotHaveThisElement" are being deprecated as they are rather limited in what they support. This resolves #970.

@@ -142,7 +142,13 @@ public T doesNotHaveThisElement(final Object val) {
@Override
public T hasThisElement(final Object val) {
Assert.parametersNotNull("val", val);
return addCriteria(FilterOperator.ELEMENT_MATCH, val, false);
return addCriteria(FilterOperator.ELEMENT_MATCH, val, not);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did the 3rd param just from false to 'not'? Is this fixing a bug?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is. It's currently not possible to negate this operation because of that hard coded 'false'

Copy link
Contributor

@jyemin jyemin Sep 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that bug reported? If not, it should be so we can track that it's getting fixed. Also, ensure that the bug fix should be done in a separate commit from the new feature work for elemMatch (I didn't check).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping on this last comment. Really should avoid drive-by bug fixes like this. Open a separate issue and fix it separately.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rolled back that fix but hadn't filed the issue. I'll do that now.

@@ -369,37 +391,67 @@ public void testElemMatchQueryCanBeNegated() {

Mapper mapper = getMorphia().getMapper();

List<Key<PhotoWithKeywords>> keys = getDs().find(PhotoWithKeywords.class)
validate(pwk1, pwk2, pwk3, pwk4, mapper, getDs().find(PhotoWithKeywords.class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate and validate2 are not testing what the test method says it is: that elemMatch queries can be negated. Only validate3 is doing that. So put the validate/validate2 assertions in a separate test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those are literally just refactorings of existing tests in to methods so i can use both elemMatch queries with the same asserts. I didn't change what they were testing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I see that the validate methods are a refactoring. But a bunch more assertions have been added to this test method and I'm suggesting that it would be better to restructure into multiple test methods whose named better describe what it is that is being tested. And once you've done that, the test names you've chosen will suggest what the validate* methods should be renamed to to reflect their purpose.

Let me know if this doesn't make sense and we can talk about it more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to avoid cutting too deeply but I bit the bullet and cleaned that up a bit. less code now and easier to reason about what's being asserted.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the new validate method... but there are still assertions that have nothing to do with negation in a test method called testElemMatchQueryCanBeNegated. That's just confusing, don't you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bit, yeah. there's only the one negation at the end, really. i'll brainstorm some new names. to be honest, i think this test duplicates a number of others and can probably be combined...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now.

@evanchooly
Copy link
Member Author

with the method renamed, all else is good @jyemin ?

@jyemin
Copy link
Contributor

jyemin commented Sep 7, 2016

I'd still like to see the bug on the existing method reported and the fix pulled out into a separate commit.

@jyemin
Copy link
Contributor

jyemin commented Sep 7, 2016

LGTM

@evanchooly evanchooly merged commit 94a1bbc into master Sep 7, 2016
@evanchooly evanchooly removed the bug label Sep 7, 2016
@evanchooly evanchooly deleted the hasThisElement branch September 16, 2016 17:32
evanchooly added a commit that referenced this pull request Oct 10, 2016
* use a query for complex hasThisElement clauses?

* introduce elemMatch() with better semantics

* expand tests to ensure old and new methods are tested.
add support for $not with $elemMatch

* deprecate `doesNotHaveThisElement`

* clean up validations

* rename method
@yizhangy
Copy link

yizhangy commented Feb 10, 2019

Hi @evanchooly
I find the the error warning message when used the "elemMatch"

Query<SelectValue> selectValueQuery = super.getMongoDatastore().createQuery(SelectValue.class);
		selectValueQuery.filter("id =", voteValueId);
		selectValueQuery.filter("checked =", true);
		
	
		
		Query<FeedMemberEntity> query = super.getMongoDatastore().find(FeedMemberEntity.class);
		query.field("feedId").equal(feedId);
		query.field("voteValues").elemMatch(selectValueQuery);
		
		return query.count();

My log had

[Validation failed: 'Type java.util.List may not be queryable with value '{ query: { "id" : "0" , "checked" : true}  }' with class xyz.morphia.query.QueryImpl', Validation failed: 'Type com.canaan.config.SelectValue may not be queryable with value '{ query: { "id" : "0" , "checked" : true}  }' with class xyz.morphia.query.QueryImpl']
Feb 10, 2019 11:04:44 PM xyz.morphia.query.QueryValidator validateQuery

Is this still a bug

@evanchooly
Copy link
Member Author

Probably related #1288

@yizhangy
Copy link

#1288

Probably related #1288

thanks refer me to this issue. It is not big issue, just a warning. we could disable the validation when make this query for now. thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

$elemMatch multiple criteria support
3 participants