tywalch/electrodb

Filter by size of a list attribute

Closed this issue · 2 comments

Describe the bug
Filter the query by using something equivalent of size(#attribute) method in DynamoDB.

ElectroDB Version
2.3.5

ElectroDB Playground Link
Link

Entity/Service Definitions

{
  model: {
    entity: "tracker",
    version: "1",
    service: "trackerapp"
  },
  attributes: {
    category: {
      type: "string",
      required: true
    },
    gameId: {
      type: "string",
      required: true
    },
    subscribers: {
      type: 'list',
      required: true,
      items: {
        type: 'map',
        required: true,
        properties: {
          emailAddress: { type: 'string', required: true },
          thresholdPrice: { type: 'number', required: true },
        },
      },
    },
    createdAt: {
      type: "number",
      default: () => Date.now(),
      // cannot be modified after created
      readOnly: true
    },
    updatedAt: {
      type: "number",
      // watch for changes to any attribute
      watch: "*",
      // set current timestamp when updated
      set: () => Date.now(),
      readOnly: true
    }
  },
  indexes: {
    category: {
      pk: { field: "pk", composite: ["category"] },
      sk: { field: "sk", composite: ['gameId'] }
    },
  }
}

Expected behavior
Be able to filter based on the size of subscribers attribute/property. Something like this:

trackers.query.category({category: 'adventure'})
  .where((item, op) => op.gt(op.size(item.subscribers), 0))
  .go();

Errors

op.size is not a function

Additional context
Add any other context about the problem here.

Hi @RaeesBhatti 👋

ElectroDB version 2.4.0 introduces a size() function within the where clause. To perform the operation you expect you can use the following syntax:

trackers.query.category({category: 'adventure'})
  .where(({ subscribers }, {size, escape}) => `
    ${size(subscribers)} > ${escape(2)}
  `)
  .go();

I will also add that the where clause is quite literally forming the FilterExpression. So you can always implement any functions and/or any other pattern without the use of specialized op functions. For example:

trackers.query.category({category: 'adventure'})
.where(({ subscribers }, {name, escape}) => `
  size(${name(subscribers)}) > ${escape(2)}
`)
.go();

Ah I see. Thank you! I tried to write a custom where clause and FilterExpression but it would just get dropped in the final query. I see now that I need to use name() to make sure it wouldn't.