|@like@, @ilike@|string|SQL pattern match, single character match is @_@ and wildcard is @%@, ilike is case-insensitive|@["properties.my_subproperty", "like", "d00220fb%"]@|
|@in@, @not in@|array of strings|Set membership|@["properties.my_subproperty", "in", ["fizz", "buzz"]]@|
|@exists@|boolean|Test if a subproperty is present or not (determined by operand).|@["properties.my_subproperty", "exists", true]@|
+|@contains@|string, number|Filter where subproperty has a value either by exact match or value is element of subproperty list.|@["foo", "contains", "bar"]@ will find both @{"foo": "bar"}@ and @{"foo": ["bar", "baz"]}@.|
Note that exclusion filters @!=@ and @not in@ will return records for which the property is not defined at all. To restrict filtering to records on which the subproperty is defined, combine with an @exists@ filter.
# format is YYYYMMDD, must be fixed with (needs to be linearly
# sortable), updated manually, may be used by clients to
# determine availability of API server features.
- revision: "20190926",
+ revision: "20200212",
source_version: AppVersion.hash,
sourceVersion: AppVersion.hash, # source_version should be deprecated in the future
packageVersion: AppVersion.package_version,
# +model_class+ subclass of ActiveRecord being filtered
#
# Output:
- # Hash with two keys:
+ # Hash with the following keys:
# :cond_out array of SQL fragments for each filter expression
# :param_out array of values for parameter substitution in cond_out
# :joins array of joins: either [] or ["JOIN containers ON ..."]
raise ArgumentError.new("Invalid operand '#{operand}' for '#{operator}' must be true or false")
end
param_out << proppath
+ when 'contains'
+ cond_out << "#{attr_table_name}.#{attr} @> ?::jsonb OR #{attr_table_name}.#{attr} @> ?::jsonb"
+ param_out << SafeJSON.dump({proppath => operand})
+ param_out << SafeJSON.dump({proppath => [operand]})
else
raise ArgumentError.new("Invalid operator for subproperty search '#{operator}'")
end
modified_at: 2015-02-13T17:22:54Z
updated_at: 2015-02-13T17:22:54Z
manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"
- name: collection with prop1 1
+ name: collection with prop2 1
properties:
prop2: 1
modified_at: 2015-02-13T17:22:54Z
updated_at: 2015-02-13T17:22:54Z
manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"
- name: collection with prop1 5
+ name: collection with prop2 5
properties:
prop2: 5
+collection_with_list_prop_odd:
+ uuid: zzzzz-4zz18-listpropertyodd
+ current_version_uuid: zzzzz-4zz18-listpropertyodd
+ portable_data_hash: fa7aeb5140e2848d39b416daeef4ffc5+45
+ owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+ created_at: 2015-02-13T17:22:54Z
+ modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+ modified_by_user_uuid: zzzzz-tpzed-d9tiejq69daie8f
+ modified_at: 2015-02-13T17:22:54Z
+ updated_at: 2015-02-13T17:22:54Z
+ manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"
+ name: collection with list property with odd values
+ properties:
+ listprop: [elem1, elem3, 5]
+
+collection_with_list_prop_even:
+ uuid: zzzzz-4zz18-listpropertyeven
+ current_version_uuid: zzzzz-4zz18-listpropertyeven
+ portable_data_hash: fa7aeb5140e2848d39b416daeef4ffc5+45
+ owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+ created_at: 2015-02-13T17:22:54Z
+ modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+ modified_by_user_uuid: zzzzz-tpzed-d9tiejq69daie8f
+ modified_at: 2015-02-13T17:22:54Z
+ updated_at: 2015-02-13T17:22:54Z
+ manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"
+ name: collection with list property with even values
+ properties:
+ listprop: [elem2, 4, elem6, ELEM8]
+
+collection_with_listprop_elem1:
+ uuid: zzzzz-4zz18-listpropelem1
+ current_version_uuid: zzzzz-4zz18-listpropelem1
+ portable_data_hash: fa7aeb5140e2848d39b416daeef4ffc5+45
+ owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+ created_at: 2015-02-13T17:22:54Z
+ modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+ modified_by_user_uuid: zzzzz-tpzed-d9tiejq69daie8f
+ modified_at: 2015-02-13T17:22:54Z
+ updated_at: 2015-02-13T17:22:54Z
+ manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"
+ name: collection with list property with string value
+ properties:
+ listprop: elem1
+
collection_with_uri_prop:
uuid: zzzzz-4zz18-withuripropval1
current_version_uuid: zzzzz-4zz18-withuripropval1
['prop2', '<=', 5, [:collection_with_prop2_1, :collection_with_prop2_5], []],
['prop2', '>=', 1, [:collection_with_prop2_1, :collection_with_prop2_5], []],
['<http://schema.org/example>', '=', "value1", [:collection_with_uri_prop], []],
+ ['listprop', 'contains', 'elem1', [:collection_with_list_prop_odd, :collection_with_listprop_elem1], [:collection_with_list_prop_even]],
+ ['listprop', '=', 'elem1', [:collection_with_listprop_elem1], [:collection_with_list_prop_odd]],
+ ['listprop', 'contains', 5, [:collection_with_list_prop_odd], [:collection_with_list_prop_even, :collection_with_listprop_elem1]],
+ ['listprop', 'contains', 'elem2', [:collection_with_list_prop_even], [:collection_with_list_prop_odd, :collection_with_listprop_elem1]],
+ ['listprop', 'contains', 'ELEM2', [], [:collection_with_list_prop_even]],
+ ['listprop', 'contains', 'elem8', [], [:collection_with_list_prop_even]],
+ ['listprop', 'contains', 4, [:collection_with_list_prop_even], [:collection_with_list_prop_odd, :collection_with_listprop_elem1]],
].each do |prop, op, opr, inc, ex|
test "jsonb filter properties.#{prop} #{op} #{opr})" do
@controller = Arvados::V1::CollectionsController.new