使用C#驱动程序从MongoDB以指定的顺序获取文档

时间:2014-06-27 06:07:50

标签: mongodb mongodb-.net-driver

我是MongoDB的新手,我想知道是否可以按照我在数组中指定的顺序通过Id获取文档。我正在使用官方的c#驱动程序。

问题说明

我在这个集合中有一些文件

{
    "_id" : "1",
    "Name" : "Assignment 1"
}

{
    "_id" : "100",
    "Name" : "Assignment 100"
}

我有一个ID { "4", "19", "10", "6" }数组,我需要的是获取与数组中相同顺序指定的文档。

这些是我尝试的查询

  

{“_ id”:{“$ in”:[“4”,“19”,“10”,“6”]}}

{ "$or" : [{ "_id" : "4" }, { "_id" : "19" }, { "_id" : "10" }, { "_id" : "6" }] }

但是这两个查询都按以下顺序返回文档 enter image description here

但我的预期结果是

enter image description here

现在我面前的唯一选择是为数组中的每个元素分别提出db请求,我认为这是一个不好的选择。

你们中的任何人都可以引导我按照我在阵列中指定的顺序获取文档。我正在使用MongoDB C#驱动程序并期待基于C#的答案。

谢谢,
卡皮尔

1 个答案:

答案 0 :(得分:0)

好吧,我终于设法使用Aggregation框架来完成这项工作。

这是我实现它的方式。但如果有人能提出比这更好的方法,我会很高兴。

string[] fetchingIds = { "4", "19", "10", "6" };

IMongoQuery fetchQuery = Query<Assignment>.In(x => x.Id, fetchingIds);
BsonDocument match = new BsonDocument { { "$match", fetchQuery.ToBsonDocument() } };

BsonDocument currentDocument = null;
BsonDocument finalDocument = null;
BsonValue processingDocument = null;
for (int i = 0; i < fetchingIds.Length; i++)
{
    BsonElement ifStatement = new BsonElement("$eq", new BsonArray(new[] { "$_id", fetchingIds[i] }));
    BsonArray conditionStatement = new BsonArray(new[] { new BsonDocument(ifStatement), BsonValue.Create(i + 1), -1 });
    currentDocument = new BsonDocument("$cond", conditionStatement);

    if (finalDocument == null)
    {
        finalDocument = currentDocument;
    }
    else
    {
        processingDocument = null;
        BsonValue tempDoc = finalDocument["$cond"][2] as BsonDocument;

        if (tempDoc == null)
        {
            processingDocument = finalDocument["$cond"];
        }

        while (tempDoc != null)
        {
            if ((tempDoc["$cond"][2] as BsonDocument) == null)
            {
                processingDocument = tempDoc["$cond"];
                tempDoc = null;
            }
            else
            {
                tempDoc = tempDoc["$cond"][2];
            }
        }

        processingDocument[2] = currentDocument;
    }
}


BsonDocument project = new BsonDocument { { "$project", new BsonDocument 
                                                        { 
                                                           // this will return whose document
                                                            {"obj","$$ROOT"},
                                                            {"weight",finalDocument},
                                                        } 
                                         } };

BsonDocument sort = new BsonDocument { { "$sort", new BsonDocument { { "weight", 1 } } } };

var result = assignmentCollection.Aggregate(new AggregateArgs
{
    Pipeline = new[] { match, project, sort },
}).ToList();