Querying a limited number of nested objects within a doc

I would like to query for only a limited number of objects in a nested collection and I can’t figure out how to do it. I am currently using Couchbase.Lite (.NET), db019.

To explain the problem, let me use a variation of Priya’s example in this topic

{
   "type":"university",
   "students":[
        {
         "id":"student_112"
		 "class":"3"
		 "order":"1"
        },
        {
         "id":"student_189"
		 "class":"2"
         "order":"5"
		},
        {
         "id":"student_1209"
		 "class":"3"
		 "order":"15"
        }
        {
         "id":"student_1215"
		 "class":"3"
		 "order":"4"
        }
		{
         "id":"student_1220"
		 "class":"5"
		 "order":"11"
        }
		{
         "id":"student_1221"
		 "class":"3"
		 "order":"25"
        }
    ]
 }

I would like to query for the students satisfying class = 3, odererd by order and return only the top 2. So I am looking for the following result:
{
“id”:"student_112"
“class”:"3"
“order”:“1”
}
and
{
“id”:"student_1215"
“class”:"3"
“order”:“4”
}

Is that possible using the current api? If so, how?
Thanks for your help!

You can query for the “students” array filtered by “class” using a query similar to one below (DB021) but currently there isn’t a way to unnest /flatten the nested array in order to apply the orderBy on the members of the nested array. (at least none that I can think of)

    let VAR_STUDENTCLASS = ArrayExpression.variable("student.class")
    let searchQuery = Query
        .select(SelectResult.expression(Meta.id),
                SelectResult.all())
        .from(DataSource.database(db))
        .where(Expression.property("type").equalTo("university")
            .and(ArrayExpression.any("student").in(Expression.property("students"))
                .satisfies(VAR_STUDENTCLASS.equalTo("3"))))

Dear Priya,

thanks for taking the time to answer my question and for clarifying the matter!

Unfortunately it is not the answer I was hoping for :slightly_smiling_face:

The number of items in the nested array (the ‘students’) can get pretty large, so I was hoping I could only look at the top items, say top 10, and fetch more from the database only if and when needed and explicitly requested.
So as far as I can see, that leaves me with either the choice of always loading the complete nested array or changing the data model to one using reference instead of embedding.

Oh well, I’ll figure something out.
Nonetheless, thanks again for your help!

Yeah …If the array is expected to be very long then I would recommend modeling the data to use the “reference” model/ normalization . The alternative would be to fetch the students array and use language features like map / filter to extract relevant elements .

If it’s enough to worry about performance, they should probably be separate documents, as Priya said. But this sounds a bit like premature optimization. Have you tested performance and found it too slow?

Dear Jens,

you’re absolutely correct, it is premature. That’s why we decided to worry about it later, if and when it becomes a real problem and not just a theoretical one.

No, we have not tested performance and it might indeed be a while before this becomes a real issue. It just seems so ‘wasteful’ to always load thousands of items when you hardly ever need more than 20. But that’s more of an emotional issue, I guess.
Once it does indeed become a real problem, then there is always the alternative of changing the datamodel. So that’s fine.

Thanks to you both for taking the time to discuss this with me!