WixData .contains() method unknown limitations?

I am attempting to create search functionality for our database of blog posts. The blog posts App collection comes with a “plainContent” field that according to this post https://support.wix.com/en/article/velo-wix-blog-posts-collection-fields should be able to use the .contains() search parameter.

However, regardless if I’m using a setFilter function or a direct wixData query it refuses to find any matches against this field. The exact same code and keys words work fine on the title parameter.

let stringInput = $w('#search').value; 

wixData.query("Blog/Posts")
.contains("plainContent", stringInput)
.find()
.then((results) => { 
    console.log(results) 
})

I’m wondering if the plainContent text field content is too large on every blog post and the contains function has an undocumented limitation on how many characters it is willing to search. If this is so, is there a way for me to bypass this limitation with some sort of manual implementation?


There is a couple of ways to attack this. I checked in the API docs and the default is 50.

Here’s the blurb:
By default, limit is set to 50.
The maximum value that limit() can accept is 1000.
Note that for some Wix app collections, the maximum value limit() can accept is less than 1000. For example, the maximum limit for the Wix Stores/Product collection is 100.

Now you can try a count() to see how many rows you expect to get back based on your search criteria (.contains()).

Sample count code:

wixData.query("Blog/Posts")
    .contains("plainContent", stringInput)
    .count()
    .find()
    .then( (num) => { 
        console.log("Number of records that match the search result is: "+num.toString());
    })
    .catch( (error) => {
        console.log("Error detected trying to query [Blog/Posts]. Error is : "+error.message);
    });

What did you see in the console.log(results) printout.

For my solution it was always 0, no results. Same thing from your solution it appears to not even be searching the plain Content at all as I can copy a word directly from an entry and it will not find it in the query. I can see that the limit of the return is 50 by default, but it isn’t finding a single result.

I can grab a word directly from the plain content field.

I can then search for just that word.

And even in such a confined circumstance my results are still nothing.

This makes me think that there is a max character limit on the contains method and it isn’t even trying to find a substring.

To follow up, a solution may be to query my entire blog database, and then use vanilla javaScript to find a substring of the plainContent field.

When found, update a new array with matches, and then populate a repeater with this new array.

However, as the blog collection only support querying 100 results and these objects are very large, I am desperately trying to avoid this workaround. Its both slower, more fragile and doesn’t technically search the entire database, though the last 100 results would suffice.

That seems like a sledgehammer approach. If you have a lot of blogs, that is going to be DOG SLOOOOWWW. If you do go down that road, make sure you do it in the backend where it will run faster.

I would just confirm with a console.log(), just before you run the query to see what ‘stringInput’ contains. You want to be double sure that the value is making it into the function. If it is, then it’s time to call technical support, since you may have uncovered a bug. You are doing everything right from what I can see.

Here are the specs for the variable you are querying:

Plain Content (plainContent)
Description : The text of the post without any formatting.
Type : Text
Can connect to data : Yes
Can use in dynamic page URL : No
Can be sorted : No
Can be filtered : contains, hasSome, hasAll, startsWith
Read-only : Yes

It clearly says that you can use: contains(), hasSome(), hasAll(), and startsWith() as valid search criteria.

Definitely keep us posted as to what the solution was.

This is a last resort for me.

I am having trouble utilizing the backend as these blog posts are sensitive to our site members. As far as I’m away the http functions I can use for a backend API don’t support authentication. Which means I would have to open my database access to public. A work around I think would be to use CORS to validate that the request was coming from my site, but I think this still opens up a security vulnerability, if other members were smart enough to make a request to the API from another page.

I have no direct solution yet. I will be contacting technical support to see if they can give me an answer. The thing that I have discovered that is strange is that the Wix App “Site Search” actually supports running the exact query I am trying to run manually. It searches the plainContent field just fine. I just don’t want to be limited by having a dedicated search page, and would rather filter my posts repeater directly in page.

@javan-friedel Let me ask you, on your front end, your members login and then want to search the blogs. If they have logged, you can make the collection secure to only allow members access to the information. I find doing the data stuff in the backend MUCH MORE secure then in the front end. First, I can hide the fields, collections names etc. It is also much faster for the backend to read from the collection, and then put all the information into a object and then transfer the completed object to the front end. I think that the approach of doing the search in the backend, and setting the correct permissions on your collection will keep your data secure. This will prevent it from having public access.

Go into Collection manager, click on your collection you need to protect, go into the permissions settings, and then select ‘Custom Permissions’ and then set read/write to be members only. If you want only the member to be able to update/delete his/her own blogs only, you can set that with the custom permissions.

@pekrzyz I believe I must be getting something mixed up. As all HTTP functions created, run without permissions. Which means they are unable to query a database that is set to anything but public. So if I set a database to read/write members only, the backend itself no longer has access to this collection. You will always get a permissions error when attempting to do this.

I’ve read briefly you can set up CORS authentication but haven’t completed my research on this yet. I could create a backend web module as well, but I don’t think this actually runs on the server, it only imports modules to use in the front end.

Any help or insight you have on this topic is extremely useful.