How can I filter with the GetAll('entry')?

Hi, I’m migrating a web from DatoCMS to Builder. Previously, I had a query filter like this:

    const { allBlogs } = await dato().GetAlBlogs({
      search,
      minYear,
      maxYear,
      dataProvided: dataProvided && {
        pattern: buildRegexp(dataProvided),
        caseSensitive: false
      },
    });

How could I do this with

await builder.getAll('blog-model', {
      options: { noTargeting: true },
      omit: 'data.blocks',
      limit: 100,
    });

basically, the search is an input, so it would have to be something like ‘includes’ in javascript.

thanks

Hi @emiliano, you can use the query option to set a search query here. Here is an example for how you could search the title field:

await builder.getAll("blog-model", {
      options: { noTargeting: true },
      limit: 100,
      query: { data: { title: { $regex: searchQuery }}}
      }
    )

You can find some more details about this on this forum post:

You can also check out our Algolia plugin for more search capabilities: Algolia Plugin | Builder.io - Builder.io

Thanks,
Sarah

Thanks for answering @sarah ! Just some doubts:

  • I can’t add javascript there… for example, I want to do toLowerCase() to title, so it’s easier to match the searchQuery

  • Or for example, I want to filter by date, so previously I did this: Number(entry.date.slice(0, 4)) <= maxYear.getFullYear()… how can I do that now?

  • Also, I have a field called dataProvided, which consists of a string of words separated by commas. So each word represents a filter that entry accomplish.
    Befor I did this:

const dataProvidedArray = dataProvided.split(', ')
const filtered = entries.filter(item => dataProvidedArray.some(data => item.dataProvided.includes(data)));

(dataProvidedArray comes from the query)

Thanks!!

Hi @emiliano,

Can you elaborate a little on how to you want to use toLowerCase()?

To filter by date you could use something like the example below:
query: {createdDate: {$gt: timestamp}}

To search for multiple values in an array, you can use something like this:
const regexSearch = dataProvidedArray.join("|")
query: { data: { title: { $regex: regexSearch }}}

For your reference, you can see all of the mongodb query operators that can be used here: https://www.mongodb.com/docs/manual/reference/operator/query/

Thanks for answering!

  • the toLowerCase() I would use it because the ‘title’ might be, for example, ‘Getting Started with Scale’, and the user in the search input would type: ‘getting started with scale’, or ‘getting started with Scale’… so if I transform both title and search input to lower case, I would prevent those bugs.

  • The timestamp isnt just a date… I have a minyear and a maxyear to filter, so they can be 2006, 2007, 2008, 2022, etc… So I need to slice the date coming from Builder to just the year (so the first 4 digits).

Thanks!

Hi @emiliano ,

You can use the $and operator to combine logic in the query. You can also use the toLowerCase() method. Here is an example:

query: {$and: [
        {createdDate: {$gt: timestamp}}, 
        {createdDate: {$lt: timestamp}},
        {name: {$regex: string.toLowerCase()}}
      ]}

You can use unix timestamps here.

Thanks! but this way I still cant add javascript to title, name, date, etc (the builder fields)…
I would like to do something like this…

Hi @emiliano , you’re correct, this will not work, but you could work around this by getting unfiltered data and then running these methods afterwards.

Hi again Sarah, I was searching and testing and I accomplish to do all the filters except for one.

Currently I have this code:

    const sets = await builder.getAll('open-dataset', {
      options: { noTargeting: true },
      omit: 'data.blocks',
      limit: 100,
      query: {
        data: {
          date: { $gte: newMinYear, $lte: newMaxYear },
          title: { $regex: search, $options: 'i' },
          annotation: { $regex: annotationArray && annotationArray.join(' '), $options: 'i' },
        }
      }
    });

The date and title filter work fine, but the annotation doesn’t. The annotation field consists in a string of words separated by commas, like Video, Image, GPS or whatever combination with video, image, GPS and lidar.

The annotation array is the filter I want to match, it consists of an array of strings of whatever combination of the same that above (video, image, GPS and lidar).

My objective is to fetch all the entries that contain one or more of the items of the array. So, for example, if the annotation array is [‘Video’, ‘Image’, ‘Lidar’], I want to fetch all the entries that have at least one of them in the annotation field.

Currently, my code isn’t working, because with that $regex I’m searching for those entries that match the entire array… following the example above, those whose annotation field consists in ‘Video, Image, Lidar’, and not the ones that have for example only ‘Video’.

I was wondering if I could do some workaround like this one I found:

db.collection.aggregate([
  {
    "$addFields": {
      "split": {
        "$split": [
          "$diversity",
          ", "
        ]
      }
    }
  },
  {
    "$match": {
      $expr: {
        $gt: [
          {
            $size: {
              "$setIntersection": [
                "$split",
                [
                  "video",
                  "gps"
                ]
              ]
            }
          },
          0
        ]
      }
    }
  },
  {
    "$project": {
      split: false
    }
  }
])

But I’m struggling with it.

Thanks!

Hi @emiliano,

I responded to this question here: FIlter entries inside the query - #2 by sarah