Skip to content
Browse files

Map Maybe[Bool] differently from Bool. Bool fields treat undef as false.

Maybe[Bool] fields treat undef as NULL / missing.

Closes #26
  • Loading branch information...
1 parent 0f75446 commit bb2426cfc8fae9f58f09e3cf9860e92051d4909d @clintongormley committed Nov 22, 2012
View
35 lib/Elastic/Manual/Attributes.pod
@@ -615,17 +615,42 @@ memory used.
=head1 BOOLEAN FIELDS
-Boolean fields accept C<undef>, C<0>, C<""> and C<"false"> as C<false> values,
+Boolean fields accept C<0>, C<""> and C<"false"> as C<false> values,
and any other value as C<true>.
There are no C<boolean>-specific keywords, but the general keywords apply:
L</index>, L</include_in_all>, L</boost>, L</multi>,
L</index_name>, L</store> and L</null_value>.
-B<Note>: By default, ElasticSearch treats C<undef> as NEITHER C<true> NOR
-C<false>, but as C<null> (ie missing). To work around this, we automatically
-set L</null_value> to C<0> to make C<boolean> fields more Perlish. If you
-would like to revert to the default behaviour, set L</null_value> to C<undef>.
+B<IMPORTANT>: Moose and Perl consider C<undef> to be an acceptable C<false>
+value. However, an C<undef> in Perl is converted to a C<null> in JSON, which
+Elasticsearch would understand as meaning "this field has no value" or
+"is missing".
+For this reason we distinguish fields the type constraint of C<Bool>
+from the type constraint of C<Maybe[Bool]> (although functionally they
+are identical in Moose).
+
+C<Bool> fields regard C<undef> as C<false>, while C<Maybe[Bool]> would regard
@timbunce
timbunce added a note Nov 22, 2012

Would be good if this sentence clarified who/what "would regard", i.e. ES, not Perl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+C<undef> as C<NULL>, "missing" or "not set".
+
+ Value Bool Maybe[Bool]
+ ---------------------------------------------
+ 1 True True
+ 0 False False
+ Empty string False False
+ Undef False NULL / missing
+ No value NULL / missing NULL / missing
+
+This is done by mapping C<Maybe[Bool]> fields as:
+
+ { type => 'boolean' }
+
+and mapping C<Maybe[Bool]> fields as:
@timbunce
timbunce added a note Nov 22, 2012

Shouldn't that be C < Bool > ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ { type => 'boolean', null_value => 0 }
+
+B<Note:> the `null_value` setting only affects how a boolean field is
+queryable - it doesn't change the actual value of the field in the object.
@timbunce
timbunce added a note Nov 22, 2012

Perhaps s/queryable/indexed by ElasticSearch/ ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
=head1 BINARY FIELDS
View
16 lib/Elastic/Model/TypeMap/Moose.pm
@@ -85,8 +85,13 @@ has_type 'HashRef',
has_type 'Maybe',
#===================================
deflate_via { _flate_maybe( 'deflator', @_ ) },
- inflate_via { _flate_maybe( 'inflator', @_ ) },
- map_via { _content_handler( 'mapper', @_ ) };
+ inflate_via { _flate_maybe( 'inflator', @_ ) }, map_via {
+ my $tc = $_[0];
+ return ( type => 'boolean' )
+ if $tc->can('type_parameter')
+ and $tc->type_parameter->name eq 'Bool';
+ _content_handler( 'mapper', @_ );
+ };
#===================================
has_type 'Moose::Meta::TypeConstraint::Enum',
@@ -235,7 +240,12 @@ In/deflation via L</Any>. It is mapped as:
An undef value is stored as a JSON C<null>. The mapping and in/deflation depend
on the content type, eg C<Maybe[Int]>. A C<Maybe> without a content
-type is mapped and in/deflated via L</Any>
+type is mapped and in/deflated via L</Any>. C<Maybe[Bool]> is special cased
+to be mapped as:
+
+ { type => 'boolean' }
+
+See L<Elastic::Manual::Attributes/BOOLEAN FIELDS> for an explanation.
=head2 Undef
View
36 t/10_typemaps/01_map_moose.t
@@ -5,27 +5,29 @@ use warnings;
our $test_class = 'TypeTest::Moose';
our @mapping = (
- 'any' => { type => 'object', enabled => 0 },
- 'item' => { type => 'object', enabled => 0 },
- 'maybe' => { type => 'object', enabled => 0 },
- 'defined' => { type => 'object', enabled => 0 },
- 'value' => { type => 'object', enabled => 0 },
- 'ref' => { type => 'object', enabled => 0 },
- 'scalar_ref' => { type => 'object', enabled => 0 },
- 'array_ref' => { type => 'object', enabled => 0 },
- 'hash_ref' => { type => 'object', enabled => 0 },
- 'hash_ref_str' => { type => 'object', enabled => 0 },
- 'hash_ref_coderef' => { type => 'object', enabled => 0 },
- 'code_ref' => { type => 'object', enabled => 0 },
- 'glob_ref' => { type => 'object', enabled => 0 },
- 'file_handle' => { type => 'object', enabled => 0 },
- 'union' => { type => 'object', enabled => 0 },
+ 'any' => { type => 'object', enabled => 0 },
+ 'item' => { type => 'object', enabled => 0 },
+ 'maybe' => { type => 'object', enabled => 0 },
+ 'defined' => { type => 'object', enabled => 0 },
+ 'value' => { type => 'object', enabled => 0 },
+ 'ref' => { type => 'object', enabled => 0 },
+ 'scalar_ref' => { type => 'object', enabled => 0 },
+ 'array_ref' => { type => 'object', enabled => 0 },
+ 'hash_ref' => { type => 'object', enabled => 0 },
+ 'hash_ref_str' => { type => 'object', enabled => 0 },
+ 'hash_ref_coderef' => { type => 'object', enabled => 0 },
+ 'code_ref' => { type => 'object', enabled => 0 },
+ 'glob_ref' => { type => 'object', enabled => 0 },
+ 'file_handle' => { type => 'object', enabled => 0 },
+ 'union' => { type => 'object', enabled => 0 },
'maybe_str' => { type => 'string' },
- 'maybe_coderef' => { type => 'object', enabled => 0 },
+ 'maybe_bool' => { type => 'boolean' },
+ 'maybe_coderef' => { type => 'object', enabled => 0 },
+ 'bool' => { type => 'boolean', null_value => 0 },
'str' => { type => 'string' },
'scalar_ref_str' => { type => 'string' },
'array_ref_str' => { type => 'string' },
- 'array_ref_coderef' => { type => 'object', enabled => 0 },
+ 'array_ref_coderef' => { type => 'object', enabled => 0 },
'subtype_str' => { type => 'string' },
'enum' => {
type => 'string',
View
36 t/10_typemaps/02_map_moosex.t
@@ -5,27 +5,29 @@ use warnings;
our $test_class = 'TypeTest::MooseX';
our @mapping = (
- 'any' => { type => 'object', enabled => 0 },
- 'item' => { type => 'object', enabled => 0 },
- 'maybe' => { type => 'object', enabled => 0 },
- 'defined' => { type => 'object', enabled => 0 },
- 'value' => { type => 'object', enabled => 0 },
- 'ref' => { type => 'object', enabled => 0 },
- 'scalar_ref' => { type => 'object', enabled => 0 },
- 'array_ref' => { type => 'object', enabled => 0 },
- 'hash_ref' => { type => 'object', enabled => 0 },
- 'hash_ref_str' => { type => 'object', enabled => 0 },
- 'hash_ref_coderef' => { type => 'object', enabled => 0 },
- 'code_ref' => { type => 'object', enabled => 0 },
- 'glob_ref' => { type => 'object', enabled => 0 },
- 'file_handle' => { type => 'object', enabled => 0 },
- 'union' => { type => 'object', enabled => 0 },
+ 'any' => { type => 'object', enabled => 0 },
+ 'item' => { type => 'object', enabled => 0 },
+ 'maybe' => { type => 'object', enabled => 0 },
+ 'defined' => { type => 'object', enabled => 0 },
+ 'value' => { type => 'object', enabled => 0 },
+ 'ref' => { type => 'object', enabled => 0 },
+ 'scalar_ref' => { type => 'object', enabled => 0 },
+ 'array_ref' => { type => 'object', enabled => 0 },
+ 'hash_ref' => { type => 'object', enabled => 0 },
+ 'hash_ref_str' => { type => 'object', enabled => 0 },
+ 'hash_ref_coderef' => { type => 'object', enabled => 0 },
+ 'code_ref' => { type => 'object', enabled => 0 },
+ 'glob_ref' => { type => 'object', enabled => 0 },
+ 'file_handle' => { type => 'object', enabled => 0 },
+ 'union' => { type => 'object', enabled => 0 },
'maybe_str' => { type => 'string' },
- 'maybe_coderef' => { type => 'object', enabled => 0 },
+ 'maybe_bool' => { type => 'boolean' },
+ 'maybe_coderef' => { type => 'object', enabled => 0 },
+ 'bool' => { type => 'boolean', null_value => 0 },
'str' => { type => 'string' },
'scalar_ref_str' => { type => 'string' },
'array_ref_str' => { type => 'string' },
- 'array_ref_coderef' => { type => 'object', enabled => 0 },
+ 'array_ref_coderef' => { type => 'object', enabled => 0 },
'subtype_str' => { type => 'string' },
'enum' => {
type => 'string',
View
14 t/lib/TypeTest/Moose.pm
@@ -32,6 +32,13 @@ has 'maybe_str_attr' => (
);
#===================================
+has 'maybe_bool_attr' => (
+#===================================
+ is => 'ro',
+ isa => 'Maybe[Bool]',
+);
+
+#===================================
has 'maybe_coderef_attr' => (
#===================================
is => 'ro',
@@ -60,6 +67,13 @@ has 'value_attr' => (
);
#===================================
+has 'bool_attr' => (
+#===================================
+ is => 'ro',
+ isa => 'Bool',
+);
+
+#===================================
has 'str_attr' => (
#===================================
is => 'ro',
View
14 t/lib/TypeTest/MooseX.pm
@@ -33,6 +33,13 @@ has 'maybe_str_attr' => (
);
#===================================
+has 'maybe_bool_attr' => (
+#===================================
+ is => 'ro',
+ isa => Maybe [Bool],
+);
+
+#===================================
has 'maybe_coderef_attr' => (
#===================================
is => 'ro',
@@ -61,6 +68,13 @@ has 'value_attr' => (
);
#===================================
+has 'bool_attr' => (
+#===================================
+ is => 'ro',
+ isa => Bool,
+);
+
+#===================================
has 'str_attr' => (
#===================================
is => 'ro',

0 comments on commit bb2426c

Please sign in to comment.
Something went wrong with that request. Please try again.