简体   繁体   English

两个 collections 的 ObjectId 的简单 $lookup “左连接”在 Mongo DB 中不起作用

[英]Simple $lookup “left join” of the ObjectId of two collections not working in Mongo DB

I am using Mongo DB Atlas with node.js and oboe (oboe streams the results to html).我正在使用带有 node.js 和双簧管的 Mongo DB Atlas(双簧管将结果流式传输到 html)。 I am new to this all, just learning all these technologies, so explaining in simpler terms will be appreaciated.我对这一切都很陌生,只是学习了所有这些技术,所以用更简单的术语解释会很受欢迎。

The goal is to do a $lookup between two collections, in this case, the collection of 'review' to 'place'.目标是在两个 collections 之间进行 $lookup,在本例中,将“review”集合到“place”。 I've researched similar answers, but the either didn't work or were using strings, not ObjectIds.我研究了类似的答案,但要么不起作用,要么使用的是字符串,而不是 ObjectIds。

It's quite simple, just connect the ObjectIds of both of the collections, but I am not able to pull the data out from the "left joined" collection of 'places' when using oboe (see oboe code at bottom, FWIW).这很简单,只需连接两个 collections 的 ObjectId,但是在使用双簧管时,我无法从“位置”的“左连接”集合中提取数据(参见底部的双簧管代码,FWIW)。

Here is a look at a document from both collections, then the code.下面是从collections看一个文档,然后是代码。 What am I doing wrong?我究竟做错了什么? I have tried converting them to strings and joining with.toString() and.str, plus put 'place_id.ObjectId' and '_id.ObjectId' for localField and foreignField.我尝试将它们转换为字符串并加入.toString() 和.str,并为localField 和foreignField 加上'place_id.ObjectId' 和'_id.ObjectId'。 Another thing too, is how can I see what is in the cursor to know what I am getting?另一件事是,我如何查看 cursor 中的内容以知道我得到了什么? debug(cursor.ToArray()) didn't work. debug(cursor.ToArray()) 不起作用。 Thanks in advance.提前致谢。

review
({
  "_id": { "$oid": "5fd27fd9647f7bb815c4c946" },
  "place_id": { "$oid": "5fbc37c4fc13ae680b00002b" }, // connect this...
  "user_id": { "$oid": "5fbc10ecfc13ae232d000068" },
  "title": "Black Forest -- unforgettable!",
  "description": "The forest was great.",
  "score": { "$numberInt": "5" }
}


place
{
  "_id": { "$oid": "5fbc37c4fc13ae680b00002b" }, // connected to _id above
  "name": "Black Forest (Schwarzwald)",
  "category": "activity",
  "city": "Freiburg",
  "country": "Germany",
  "description": "The Black Forest (German: Schwarzwald [ˈʃvaʁtsvalt] (About this soundlisten)) is a large forested mountain range.]",
  "image": { "filename": "1607629020164_black_forest.jpg", "mime": "image/jpeg" },
  "state": ""
})

router.get('/', async (req, res, next) => {
  debug('get all reviews api');
  try {
    const q = req.query.q;
    const collation = { locale: 'en_US', strength: 1 };

    const matchStage = {};
    if (q) {
      matchStage.$text = { $search: q };
    }
    const pipeline = [
      {
        $match: matchStage,
      },
      {
        $lookup: {
          from: 'place',
          localField: 'place_id',
          foreignField: '_id',
          as: 'place',
        },
      },
    ];
    const connection = await db.connect();
    const cursor = connection.collection('review').aggregate(pipeline, { collation: collation });


    // write the JSON file
    res.type('application/json');
    res.write('[\n');
    for await (const doc of cursor) {
      res.write(JSON.stringify(doc));
      res.write(',\n');
    }
    res.end('null]');
  } catch (err) {
    sendError(err, res);
  }
});

The cursor goes to oboe and becomes an 'item'. cursor 成为双簧管并成为“物品”。 I would expect to use a template string such as {item.place.name} to get the data when putting this into html.在将其放入 html 时,我希望使用诸如{item.place.name}之类的模板字符串来获取数据。 That's how I would access it, right?这就是我访问它的方式,对吧?

    const performSearch = () => {
      seen = 0;
      $('stream-data-spinner').removeClass('d-none');
      $('#search-results').html('');
      const formData = $('#search-place-form').serialize();

      oboe('/api/review?' + formData)
        .node('![*]', (item) => {
          if (item) {
            chunk.push(item);
            if (chunk.length >= 1000) {
              showChunk(chunk);
            }
          }
          return oboe.drop;
        })
        .done((_) => {
          // show the last chunk
          showChunk(chunk);
          // hide the spinner
          outputSpinner.classList.add('d-none');
        })
        .fail((res) => {
          // show the error
          outputSeen.textContent = `ERROR: network error`;
          outputSeen.classList.add('text-danger');
          outputSpinner.classList.add('text-danger');
        });
    };

From your MongoDB aggregation query, your place field is an array.从您的 MongoDB 聚合查询中,您的place字段是一个数组。 You may want to $unwind it to flatten it into object for your oboe code to access it.您可能想要$unwind将其展平为 object 以便您的双簧管代码访问它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM