Ссылка на другие коллекции с PyMongo [duplicate]

TL; DR: Попробуйте использовать Html.Partial вместо Renderpage


Я получал Object reference not set to an instance of an object, когда пытался сделать вид в представлении, отправив ему модель, например это:

@{
    MyEntity M = new MyEntity();
}
@RenderPage("_MyOtherView.cshtml", M); // error in _MyOtherView, the Model was Null

Отладка показала, что модель была Null внутри MyOtherView. Пока я не сменил его на:

@{
    MyEntity M = new MyEntity();
}
@Html.Partial("_MyOtherView.cshtml", M);

И это сработало.

Кроме того, причина, по которой я не имел Html.Partial для начала, заключалась в том, что Visual Studio иногда выдает ошибки, (f9), если он находится внутри другого построенного цикла foreach, хотя это не ошибка:

@inherits System.Web.Mvc.WebViewPage
@{
    ViewBag.Title = "Entity Index";
    List<MyEntity> MyEntities = new List<MyEntity>();
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
}
<div>
    @{
        foreach(var M in MyEntities)
        {
            // Squiggly lines below. Hovering says: cannot convert method group 'partial' to non-delegate type Object, did you intend to envoke the Method?
            @Html.Partial("MyOtherView.cshtml");
        }
    }
</div>

Но я смог запустить приложение без проблем с этим " ошибка". Я смог избавиться от ошибки, изменив структуру цикла foreach, чтобы выглядеть так:

@foreach(var M in MyEntities){
    ...
}

Хотя я чувствую, что это потому, что Visual Studio неправильно интерпретировала амперсанды и скобки .

28
задан L.J.W 30 December 2010 в 15:04
поделиться

10 ответов

Вы не можете делать то, что хотите, в одном запросе. Вам нужно будет сначала получить список идентификаторов пользователей друга, а затем передать эти идентификаторы во второй запрос, чтобы получить документы и отсортировать их по возрасту.

var user = db.user.findOne({"id" : "001"}, {"friends": 1})
db.user.find( {"id" : {$in : user.friends }}).sort("age" : 1);
29
ответ дан Andrey Rubshtein 28 August 2018 в 14:56
поделиться

Вы можете использовать playOrm, чтобы делать то, что хотите в одном запросе (с S-SQL масштабируемым SQL).

0
ответ дан Dean Hiller 28 August 2018 в 14:56
поделиться

Чтобы иметь все с одним запросом, используя функцию $ lookup в структуре агрегации, попробуйте следующее:

db.User.aggregate(
    [
        // First step is to extract the "friends" field to work with the values
        {
            $unwind: "$friends"
        },
        // Lookup all the linked friends from the User collection
        {
            $lookup:
            {
                from: "User",
                localField: "friends",
                foreignField: "_id",
                as: "friendsData"
            }
        },
        // Sort the results by age
        {
            $sort: { 'friendsData.age': 1 }
        },
        // Get the results into a single array
        {
            $unwind: "$friendsData"
        },
        // Group the friends by user id
        {
            $group:
            {
                _id: "$_id",
                friends: { $push: "$friends" },
                friendsData: { $push: "$friendsData" }
            }
        }
    ]
)

Предположим, что содержимое вашей пользовательской коллекции следующее:

{
    "_id" : ObjectId("573b09e6322304d5e7c6256e"),
    "name" : "John",
    "age" : 30,
    "friends" : [
        "userId1",
        "userId2",
        "userId3"
    ]
}
{ "_id" : "userId1", "name" : "Derek", "age" : 34 }
{ "_id" : "userId2", "name" : "Homer", "age" : 44 }
{ "_id" : "userId3", "name" : "Bobby", "age" : 12 }

Результатом запроса будет:

{
    "_id" : ObjectId("573b09e6322304d5e7c6256e"),
    "friends" : [
        "userId3",
        "userId1",
        "userId2"
    ],
    "friendsData" : [
        {
            "_id" : "userId3",
            "name" : "Bobby",
            "age" : 12
        },
        {
            "_id" : "userId1",
            "name" : "Derek",
            "age" : 34
        },
        {
            "_id" : "userId2",
            "name" : "Homer",
            "age" : 44
        }
    ]
}
25
ответ дан Derek 28 August 2018 в 14:56
поделиться

Вы можете сделать это за один раз, используя mongo-join-query . Вот как это будет выглядеть:

const joinQuery = require("mongo-join-query");

joinQuery(
    mongoose.models.User,
    {
        find: {},
        populate: ["friends"],
        sort: { age: 1 },
    },
    (err, res) => (err ? console.log("Error:", err) : console.log("Success:", res.results))
);

В результате ваши пользователи будут упорядочены по возрасту и всем вложенным объектам друзей.

Как это работает?

За кулисами mongo-join-query будет использоваться ваша схема Mongoose, чтобы определить, к каким моделям присоединиться, и создаст конвейер агрегации , который будет выполнять соединение и запрос.

0
ответ дан Marcelo Lazaroni 28 August 2018 в 14:56
поделиться

Только заполнить друзей массива.

User.findOne({ _id: "userId"})
.populate('friends')
.exec((err, user) => {
    //do something
});

Результат такой же:

{
    "_id" : "userId",
    "name" : "John",
    "age" : 30,
    "friends" : [
        { "_id" : "userId1", "name" : "Derek", "age" : 34 }
        { "_id" : "userId2", "name" : "Homer", "age" : 44 }
        { "_id" : "userId3", "name" : "Bobby", "age" : 12 }
    ]
}

То же самое: Mongoose - использование Populate в массиве ObjectId

0
ответ дан Mateus Pereira 28 August 2018 в 14:56
поделиться

MongoDB не имеет объединений, но в вашем случае вы можете сделать:

db.coll.find({friends: userId}).sort({age: -1})
5
ответ дан pingw33n 28 August 2018 в 14:56
поделиться
var p = db.sample1.find().limit(2) , 
    h = [];
for (var i = 0; i < p.length(); i++) 
{
  h.push(p[i]['name']);
}
db.sample2.find( { 'doc_name': { $in : h } } ); 

он работает для меня.

0
ответ дан Piyush Dholariya 28 August 2018 в 14:56
поделиться

один вид соединения запроса в mongoDB, задает в одной коллекции идентификатор, который соответствует, помещает идентификаторы в список (idlist) и находит использование в другой (или такой же) коллекции с помощью $ in: idlist

u = db.friends.find({"friends": ? }).toArray()
idlist= []
u.forEach(function(myDoc) { idlist.push(myDoc.id ); } )
db.friends.find({"id": {$in : idlist} } )
1
ответ дан Sérgio 28 August 2018 в 14:56
поделиться

Похоже, никто не говорил об этом варианте использования Pivot в добавлении к MapReduce. Существует хорошая статья, которая может быть вашим ответом здесь http://cookbook.mongodb.org/patterns/pivot/ Надеюсь, это поможет вам в ваших проектах

2
ответ дан Stephane Paquet 28 August 2018 в 14:56
поделиться

https://docs.mongodb.org/manual/reference/operator/aggregation/lookup/

Это документ для запроса соединения в mongodb, это новый функция из версии 3.2.

Так что это будет полезно.

10
ответ дан user3280472 28 August 2018 в 14:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: