-
-
Notifications
You must be signed in to change notification settings - Fork 504
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
Prevent search index creation with dynamic: false
and empty fields
mapping
#2690
Conversation
66b0d20
to
a9bab0d
Compare
dynamic
and fields
parameters
// "mappings" is required and must be an object | ||
if (! isset($definition['mappings']) || $definition['mappings'] === []) { | ||
$definition['mappings'] = new stdClass(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to my question in mongodb/mongo-php-library#1482 (comment), I'm not sure what use case we're supporting here. If dynamic: false
is the default (per createSearchIndexes
docs), why should we allow creating a search index with no mappings at all?
The CreateSearchIndexes operation and SearchIndexInput, which it utilizes, do not validate this.
By default, when
definition.mappings
is an empty object, the server fallbacks (sic) todynamic: true
. But we don't want to implement this behavior client-side.
On a separate note, the createSearchIndexes
docs themselves say that definition.mappings
is an optional document and dynamic: false
is the default. If that's inaccurate I think a DOCSP ticket may be warranted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've completely reworked the PR to throw an exception in case none of dynamic
or fields
is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, should it go back to targeting the 2.9.x branch as a bug fix? I wouldn't consider this new functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@GromNaN: Bumping this. If you're just adding extra validation, is 2.9.x appropriate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I'm adding a new validation, I think 2.10.x is better. Currently, indexes with #[SearchIndex(dynamic: false)]
are accepted (even if they are useless).
Changing the target branch, as this would be a new feature. |
f20f9cb
to
8d99b0c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know if you disagree about using array_key_exists()
and I'll concede and LGTM.
@@ -1220,9 +1220,15 @@ public function hasIndexes(): bool | |||
*/ | |||
public function addSearchIndex(array $definition, ?string $name = null): void | |||
{ | |||
$name ??= self::DEFAULT_SEARCH_INDEX_NAME; | |||
|
|||
if (empty($definition['mappings']['dynamic']) && empty($definition['mappings']['fields'])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to check if $definition['mappings']['dynamic']
is false
also.
The condition would be:
if (empty($definition['mappings']['dynamic']) && empty($definition['mappings']['fields'])) { | |
if (! array_key_exists('mappings', $definition) || ((! array_key_exists('dynamics', $definition['mappings']) || ! $definition['mappings']) && (! array_key_exists('fields', $definition['mappings']) || ! is_array($definition['mappings']['fields']) || count($definition['mappings']['fields']) === 0)) { |
It don't think this makes the code more explicit, secure or performant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding was that the original bug only cared about both options being unspecified, so two array_key_exists()
checks would be the minimum change to implement. ODM wasn't prohibiting dynamic: true
with a non-empty fields
array (I assume the server reports an error there), so I assumed the most minimal validation would be OK.
If you instead want to prohibit dynamic: false
and an empty fields
array, the original condition was fine (and certainly more readable). Since we know the server doesn't report an error for that, I suppose having ODM validate this will protect users from creating a useless index.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally messed with github UI patches. I've reverted this change to validate the mappings is correct (dynamic or fields)
b759800
to
441ebf8
Compare
dynamic
and fields
parametersdynamic: false
and empty fields
mapping
Summary
When creating a document with
SearchIndex
configuration missing bothdynamic
andfields
config, the index definition sent to MongoDB is incorrect.definition.mappings
is required and must be an object.By default, when
definition.mappings
is an empty object, the server fallbacks todynamic: false
without fields. This mapping is useless as this means no field is mapped.Prevent this invalid configuration by throwing a MappingException when
dynamic
is not set orfalse
, andfields
is not set or empty.