3

我有一个包含如下文档的集合:

{
    "_id": ObjectId("507f191e810c19729de860ea"),
    "SubCollection": [{
        "_id": ObjectId("55849c0002cee826cc67550a"),
        "Timestamp": NumberLong(635717988841453845),
        "IsValid": true
    },
    {
        "_id": ObjectId("507f1f77bcf86cd799439011"),
        "Timestamp": NumberLong(635717988830033174),
        "IsValid": true
    }]  
}

    public class RootEntity
    {
        public ObjectId Id { get; set; }
        public List<SubEntity> SubCollection { get; set; }
    }

    public class SubEntity
    {
        public ObjectId Id { get; set; }
        public long Timestamp { get; set; }
        public bool IsValid { get; set; }
    }

我需要创建一个 mongo 查询,该查询返回仅包含第一个子集合项的文档。但是,子集合需要首先通过 IsValid bool 过滤,然后按 Timestamp 排序。

到目前为止,我有一个查询返回包含第一个子集合项的文档,但我无法让它先对子集合进行排序,这可以实现吗?

这是我到目前为止的查询,请注意我使用的是 C# .NET MongoDB Driver v2.0:

        var filter = Builders<TestFocusEntity>.Filter.And(
            Builders<RootEntity>.Filter.Eq(x => x.Id, id),
            Builders<TestFocusEntity>.Filter.ElemMatch(x => x.SubCollection, sub => test.IsValid == true));

        var result = await collection.Find(filter)
            .Sort(Builders<RootEntity>.Sort.Ascending("SubCollection.$.Timestamp"))
            .Project<RootEntity>(Builders<RootEntity>.Projection.Slice(x => x.SubCollection, 0, 1))
            .ToListAsync();

        var rootDocument = result.SingleOrDefault();
        var subDocument = rootDocument == null
            ? null
            : rootDocument.SubCollection.SingleOrDefault();
4

1 回答 1

2

The sort on the Timestamp field is going to sort the matched documents (which will have no effect as there is only at most 1 matched by id). It won't sort the array within the matched document. It's not possible to do such a sort within arrays on the DB at all in MongoDB, it's not a limitation of the C# driver.

See Mongo documentation on array sort:

With arrays ... an ascending sort compares the smallest element of arrays

i.e. it's sorting the documents by the smallest value of the array in each document, not sorting within the array.

If the SubEntity array is reasonably small, you can perform do that part of your operation in memory after pulling back the whole array.

If the SubEntity array is very large, you may want to rethink the document schema to avoid pulling back the whole document and subcollection into memory each time. For example, make each SubEntity a document in it's own right.

于 2015-07-16T18:29:49.357 回答