fix count in get and get stats if explicit ids are given and ids might be duplicated when configuration are stored in different index (versions). fixes #56196
This commit is contained in:
parent
575cafb8da
commit
a9425a0240
|
@ -120,10 +120,16 @@ public abstract class AbstractTransportGetResourcesAction<Resource extends ToXCo
|
|||
requiredMatches.filterMatchedIds(foundResourceIds);
|
||||
if (requiredMatches.hasUnmatchedIds()) {
|
||||
listener.onFailure(notFoundException(requiredMatches.unmatchedIdsString()));
|
||||
} else {
|
||||
// if only exact ids have been given, take the count from docs to avoid potential duplicates
|
||||
// in versioned indexes (like transform)
|
||||
if (requiredMatches.isOnlyExact()) {
|
||||
listener.onResponse(new QueryPage<>(docs, docs.size(), getResultsField()));
|
||||
} else {
|
||||
listener.onResponse(new QueryPage<>(docs, totalHitCount, getResultsField()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
|
|
@ -43,6 +43,7 @@ public final class ExpandedIdsMatcher {
|
|||
}
|
||||
|
||||
private final LinkedList<IdMatcher> requiredMatches;
|
||||
private final boolean onlyExact;
|
||||
|
||||
/**
|
||||
* Generate the list of required matches from the expressions in {@code tokens}
|
||||
|
@ -65,14 +66,19 @@ public final class ExpandedIdsMatcher {
|
|||
// require something, anything to match
|
||||
requiredMatches.add(new WildcardMatcher("*"));
|
||||
}
|
||||
onlyExact = false;
|
||||
return;
|
||||
}
|
||||
|
||||
boolean atLeastOneWildcard = false;
|
||||
|
||||
if (allowNoMatchForWildcards) {
|
||||
// matches are not required for wildcards but
|
||||
// specific job Ids are
|
||||
for (String token : tokens) {
|
||||
if (Regex.isSimpleMatchPattern(token) == false) {
|
||||
if (Regex.isSimpleMatchPattern(token)) {
|
||||
atLeastOneWildcard = true;
|
||||
} else {
|
||||
requiredMatches.add(new EqualsIdMatcher(token));
|
||||
}
|
||||
}
|
||||
|
@ -81,11 +87,13 @@ public final class ExpandedIdsMatcher {
|
|||
for (String token : tokens) {
|
||||
if (Regex.isSimpleMatchPattern(token)) {
|
||||
requiredMatches.add(new WildcardMatcher(token));
|
||||
atLeastOneWildcard = true;
|
||||
} else {
|
||||
requiredMatches.add(new EqualsIdMatcher(token));
|
||||
}
|
||||
}
|
||||
}
|
||||
onlyExact = atLeastOneWildcard == false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,6 +127,14 @@ public final class ExpandedIdsMatcher {
|
|||
return requiredMatches.stream().map(IdMatcher::getId).collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether ids are based on exact matchers or at least one contains a wildcard.
|
||||
*
|
||||
* @return true if only exact matches, false if at least one id contains a wildcard
|
||||
*/
|
||||
public boolean isOnlyExact() {
|
||||
return onlyExact;
|
||||
}
|
||||
|
||||
private abstract static class IdMatcher {
|
||||
protected final String id;
|
||||
|
|
|
@ -25,49 +25,58 @@ public class ExpandedIdsMatcherTests extends ESTestCase {
|
|||
requiredMatches.filterMatchedIds(Collections.singletonList("foo"));
|
||||
assertFalse(requiredMatches.hasUnmatchedIds());
|
||||
assertThat(requiredMatches.unmatchedIds(), empty());
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(ExpandedIdsMatcher.tokenizeExpression(""), false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
requiredMatches.filterMatchedIds(Collections.singletonList("foo"));
|
||||
assertThat(requiredMatches.unmatchedIds(), empty());
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(ExpandedIdsMatcher.tokenizeExpression(null), false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
requiredMatches.filterMatchedIds(Collections.singletonList("foo"));
|
||||
assertThat(requiredMatches.unmatchedIds(), empty());
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(ExpandedIdsMatcher.tokenizeExpression(null), false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
requiredMatches.filterMatchedIds(Collections.emptyList());
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
assertThat(requiredMatches.unmatchedIds().get(0), equalTo("*"));
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(ExpandedIdsMatcher.tokenizeExpression("_all"), false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
requiredMatches.filterMatchedIds(Collections.singletonList("foo"));
|
||||
assertThat(requiredMatches.unmatchedIds(), empty());
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(new String[] {"foo*"}, false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
requiredMatches.filterMatchedIds(Arrays.asList("foo1","foo2"));
|
||||
assertThat(requiredMatches.unmatchedIds(), empty());
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(new String[] {"foo*","bar"}, false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(2));
|
||||
requiredMatches.filterMatchedIds(Arrays.asList("foo1","foo2"));
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
assertEquals("bar", requiredMatches.unmatchedIds().get(0));
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(new String[] {"foo*","bar"}, false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(2));
|
||||
requiredMatches.filterMatchedIds(Arrays.asList("foo1","bar"));
|
||||
assertFalse(requiredMatches.hasUnmatchedIds());
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(new String[] {"foo*","bar"}, false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(2));
|
||||
requiredMatches.filterMatchedIds(Collections.singletonList("bar"));
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
assertEquals("foo*", requiredMatches.unmatchedIds().get(0));
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(ExpandedIdsMatcher.tokenizeExpression("foo,bar,baz,wild*"), false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(4));
|
||||
|
@ -75,6 +84,14 @@ public class ExpandedIdsMatcherTests extends ESTestCase {
|
|||
assertThat(requiredMatches.unmatchedIds(), hasSize(2));
|
||||
assertThat(requiredMatches.unmatchedIds().get(0), is(oneOf("bar", "wild*")));
|
||||
assertThat(requiredMatches.unmatchedIds().get(1), is(oneOf("bar", "wild*")));
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(new String[] {"foo","bar"}, false);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(2));
|
||||
requiredMatches.filterMatchedIds(Collections.singletonList("bar"));
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
assertEquals("foo", requiredMatches.unmatchedIds().get(0));
|
||||
assertTrue(requiredMatches.isOnlyExact());
|
||||
}
|
||||
|
||||
public void testMatchingResourceIds_allowNoMatch() {
|
||||
|
@ -84,6 +101,7 @@ public class ExpandedIdsMatcherTests extends ESTestCase {
|
|||
requiredMatches.filterMatchedIds(Collections.emptyList());
|
||||
assertThat(requiredMatches.unmatchedIds(), empty());
|
||||
assertFalse(requiredMatches.hasUnmatchedIds());
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(new String[] {"foo*","bar"}, true);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
|
@ -91,11 +109,20 @@ public class ExpandedIdsMatcherTests extends ESTestCase {
|
|||
requiredMatches.filterMatchedIds(Collections.singletonList("bar"));
|
||||
assertThat(requiredMatches.unmatchedIds(), empty());
|
||||
assertFalse(requiredMatches.hasUnmatchedIds());
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(new String[] {"foo*","bar"}, true);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
requiredMatches.filterMatchedIds(Collections.emptyList());
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
assertEquals("bar", requiredMatches.unmatchedIds().get(0));
|
||||
assertFalse(requiredMatches.isOnlyExact());
|
||||
|
||||
requiredMatches = new ExpandedIdsMatcher(new String[] {"foo","bar"}, true);
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(2));
|
||||
requiredMatches.filterMatchedIds(Collections.singletonList("bar"));
|
||||
assertThat(requiredMatches.unmatchedIds(), hasSize(1));
|
||||
assertEquals("foo", requiredMatches.unmatchedIds().get(0));
|
||||
assertTrue(requiredMatches.isOnlyExact());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,7 +453,13 @@ public class IndexBasedTransformConfigManager implements TransformConfigManager
|
|||
);
|
||||
return;
|
||||
}
|
||||
// if only exact ids have been given, take the count from docs to avoid potential duplicates
|
||||
// in versioned indexes (like transform)
|
||||
if (requiredMatches.isOnlyExact()) {
|
||||
foundIdsListener.onResponse(new Tuple<>((long) ids.size(), new ArrayList<>(ids)));
|
||||
} else {
|
||||
foundIdsListener.onResponse(new Tuple<>(totalHits, new ArrayList<>(ids)));
|
||||
}
|
||||
}, foundIdsListener::onFailure),
|
||||
client::search
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue