<?php
$args = [
'post_type' => 'my_post_type',
'orderby' => [
'date' => 'DESC',
'manual_date' => 'DESC'
],
'meta_query' => [[
'key' => 'manual_date',
'value' => current_time('Y.m.d'),
'compare' => '<='
]]
];
$posts = get_posts($args);
Первый вариант сразу отпадает, если постов, например, больше 100, или 1000. Это нагрузка на сервер, плюс сайт будет медленнее загружаться. Вообще в целом, грузить кучу контента сразу, который пользователь скорее всего не увидит, плохая затея
Можно отдавать новые посты в json и на фронте из отрисовывать
const prisma: any = {}
interface GroupedOutput {
keys: { date: string, field1: string, field2: string }
items: any[]
}
interface FindGroupedArgs {
order?: 'asc' | 'desc',
field?: string | undefined,
page: number,
limit: number,
orderNumber?: string | undefined,
prop1?: string | undefined,
prop2?: string | undefined,
}
class TestModel {
public static async findGrouped({ order = 'asc', field = 'id', ...args }: FindGroupedArgs) {
const { page, limit, orderNumber, ...query } = args
const primaryWhere = this.getPrimaryFindWhere(query)
const take = 150
const list: GroupedOutput[] = []
let prev = 0
let group = 1
let grouped = await this.loadPartOfGroupedData(group, take, primaryWhere)
dance: {
while (grouped.length) {
for await (const keys of grouped.splice(0)) {
const relatedQuery = { ...keys, prop2: query?.prop2 }
const relatedWhere = this.getRelatedFindWhere(relatedQuery, orderNumber)
const count = await prisma.relatedTable.count({ where: relatedWhere })
if (!count) continue
prev += count
if (this.isPrevGroupedPage(prev, limit, page)) continue
const total = list.reduce((acc, it) => acc + it.items.length, 0)
if (this.isNextGroupedPage(total, count, limit)) break dance
const items = await prisma.relatedTable.findMany({
where: relatedWhere,
orderBy: { id: 'desc' },
})
list.push({ keys, items })
}
grouped = await this.loadPartOfGroupedData(++group, take, primaryWhere)
}
}
const totalWhere = this.getRelatedFindWhere(query, orderNumber)
const total = await prisma.relatedTable.count({ where: totalWhere })
return { items: list, total }
}
// ****************** Private methods ****************** //
private static loadPartOfGroupedData(page: number, take: number, where: any) {
const skip = take * (page - 1)
return prisma.primaryTable.groupBy({
by: ['date', 'prop1', 'prop2'],
where, orderBy: { date: 'desc' },
take, skip,
})
}
private static isPrevGroupedPage(prev: number, limit: number, page: number) {
return prev <= (limit * page) - limit
}
private static isNextGroupedPage(total: number, count: number, limit: number) {
return total + count > limit
}
private static getPrimaryFindWhere(query: any) {
return {}
}
private static getRelatedFindWhere(query: any, orderNumber: string | undefined) {
return {}
}
}