Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

How to query only documents with an existing localization for a certain locale?

default discord avatar
hdodov12 months ago
4 1

We have a blog with posts. Some of the posts are localized. On localized versions of the website, we only want to show posts with localized content. How do we query them?

When locale is provided to payload.find(), it simply fetches all documents and uses the fallback locale content where localized content is not present. In our case, however, we want only some documents — the ones where content.{locale} is not empty. For example, if I open https://example.com/es/blog, I would only want posts where content.es is not empty.

Our current approach is this:

const localizedPostIds = (
	await payload.db.collections["blog-posts"]
		.find({
			[`content.${req.locale}`]: {
				$exists: true,
				$ne: "",
			},
		})
		.select({
			_id: true,
		})
).map((e) => e.id);

const posts = (
	await payload.find({
		collection: "blog-posts",
		locale: req.locale,
		where: {
			_id: {
				in: localizedPostIds,
			},
		},
	})
).docs;

Is there a better way? Perhaps one that doesn't use two database queries?

  • Selected Answer
    discord user avatar
    DanRibbens
    12 months ago

    I am fairly certain that the query builder does let you pass the locale through and that you should be able to just do one query. Also I do not think that querying uses the fallback locale at all. We don't have extra logic that would add or for the fallback for the properties being queried.

    It is my expectation that this should work:

    const posts = (
    	await payload.find({
    		collection: "blog-posts",
    		locale: req.locale,
    		where: {
    			'content.es': {
    				exists: true,
    			},
    		},
    	})
    ).docs;
    

    To format that into a rest query using query params you're looking at /api/blog-posts?where[content.es][exists]=true&locale=es
    That should return your posts where content is populated in the es locale AND the returned data will use your fallbackLocales as you've defined them in your localization. If you don't want the results to have fallback you can always add &fallbackLocale=null.

    Does that work?

    1 reply
  • default discord avatar
    hdodov11 months ago

    Yep, that works! I was able to reduce the two queries to a single one. Thank you!

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.