Как я избавляюсь от дочерних процессов Java, когда мое приложение Java выходит/разрушает?

Я не совсем уверен, что ваш существующий конвейер является наиболее оптимальным, но без примерных данных, которые можно использовать, трудно действительно сказать иначе. Так что просто продолжаем работать с тем, что у вас есть:

Использование $ unwind

var pipeline =  [
    // { $unwind: '$prices' }, // note: should not need this past MongoDB 3.0
    { $lookup: {
        from: 'prices',
        localField: 'prices',
        foreignField: '_id',
        as: 'prices'
     }},
     { $unwind: '$prices' },
     { $lookup: {
        from: 'stores',
        localField: 'prices.store',
        foreignField: '_id',
        as: 'prices.store'
      }},
      // Changes from here
      { $unwind: '$prices.store' },
      { $match: {'prices.store._id': mongoose.Types.ObjectId(storeId) } },
      { $group: {
        _id: '

Я не совсем уверен, что ваш существующий конвейер является наиболее оптимальным, но без примерных данных, которые можно использовать, трудно действительно сказать иначе. Так что просто продолжаем работать с тем, что у вас есть:

Использование $ unwind

[110]

Точки там начинаются с:

  • Initial [ 116] - не требуется. Только в очень ранних выпусках MongoDB 3.0 это когда-либо было требованием $unwind массива значений перед использованием $lookup для этих значений.

  • $unwind после $lookup - Всегда требуется, если вы ожидаете совпадения с «единичным» объектом, поскольку $lookup всегда возвращает массив. [ 1178] [тысяча сто семьдесят два]

  • $match после $unwind - фактически «оптимизация» для конвейерной обработки и фактически требование для «фильтрации» [ 1160]. Без $unwind это просто подтверждение того, что «что-то есть» , но элементы, которые не совпадают, не будут удалены.

  • $push в $group - Это фактическая часть, которая перестраивает массив "prices".

Ключевым моментом, который вы в основном упускали, было использование $first для содержимого «всего документа». Вы действительно никогда не хотите этого, и даже если вы хотите больше, чем просто "name", вы всегда хотите $push "prices".

На самом деле вам, вероятно, нужно больше полей, чем просто name из исходного документа, но на самом деле вам следует использовать вместо этого следующую форму.

Expressive $ lookup

Альтернатива доступна с большинством современных выпусков MongoDB начиная с MongoDB 3.6, которые, честно говоря, вы должны использовать как минимум:

var pipeline =  [
    { $lookup: {
        from: 'prices',
        let: { prices: '$prices' },
        pipeline: [
          { $match: {
            store: mongoose.Types.ObjectId(storeId),
            $expr: { $in: [ '

Я не совсем уверен, что ваш существующий конвейер является наиболее оптимальным, но без примерных данных, которые можно использовать, трудно действительно сказать иначе. Так что просто продолжаем работать с тем, что у вас есть:

Использование $ unwind

[110]

Точки там начинаются с:

  • Initial [ 116] - не требуется. Только в очень ранних выпусках MongoDB 3.0 это когда-либо было требованием $unwind массива значений перед использованием $lookup для этих значений.

  • $unwind после $lookup - Всегда требуется, если вы ожидаете совпадения с «единичным» объектом, поскольку $lookup всегда возвращает массив. [ 1178] [тысяча сто семьдесят два]

  • $match после $unwind - фактически «оптимизация» для конвейерной обработки и фактически требование для «фильтрации» [ 1160]. Без $unwind это просто подтверждение того, что «что-то есть» , но элементы, которые не совпадают, не будут удалены.

  • $push в $group - Это фактическая часть, которая перестраивает массив "prices".

Ключевым моментом, который вы в основном упускали, было использование $first для содержимого «всего документа». Вы действительно никогда не хотите этого, и даже если вы хотите больше, чем просто "name", вы всегда хотите $push "prices".

На самом деле вам, вероятно, нужно больше полей, чем просто name из исходного документа, но на самом деле вам следует использовать вместо этого следующую форму.

Expressive $ lookup

Альтернатива доступна с большинством современных выпусков MongoDB начиная с MongoDB 3.6, которые, честно говоря, вы должны использовать как минимум:

[111]

Итак, первое, на что стоит обратить внимание Это «внешний» pipeline на самом деле является просто одной $lookup стадией, так как все, что ему действительно нужно сделать, это «присоединиться» к коллекции prices. С точки зрения присоединения к вашей исходной коллекции это также верно, поскольку дополнительный $lookup в приведенном выше примере фактически связан с prices другой коллекцией.

Это именно то, что делает эта новая форма, поэтому вместо использования $unwind в результирующем массиве, а затем после объединения, только соответствующие элементы для «цен». "затем" присоединяются "к коллекции" stores ", и перед они возвращаются в массив. Конечно, поскольку существует отношение «один к одному» с «магазином», это действительно $unwind .

Короче говоря, вывод этого просто содержит исходный документ с массивом "prices" внутри. Таким образом, нет необходимости перестраивать через $group и не путать то, что вы используете $first и что вы $push . [ 1186]


ПРИМЕЧАНИЕ : я более чем подозреваю ваше утверждение «хранилища фильтров» и пытаюсь сопоставить поле store, как представлено в коллекции "prices". Вопрос показывает ожидаемый результат из двух разных магазинов, даже если вы укажете совпадение равенства.

Если что-то подозреваю, вы могли бы означать «список магазинов» , который вместо этого был бы больше похож на:

store: { $in: storeList.map(store => mongoose.Types.ObjectId(store)) }

То, как вы бы это сделали работать с «списком строк» ​​ в обоих случаях, используя $in для сопоставления со «списком» и Array.map() для работы с предоставленным списком и возвращать каждый как ObjectId() значения.

СОВЕТ : С mongoose вы используете «модель» вместо того, чтобы работать с именами коллекций, и фактические имена коллекций MongoDB обычно являются множественным числом от имени модели, которое вы зарегистрировали.

Таким образом, вам не нужно «жестко» кодировать фактические имена коллекций для $lookup, просто используйте:

   Model.collection.name
blockquote>

.collection.name является доступным свойством во всех моделях, и может избавить вас от необходимости помнить, как на самом деле назвать коллекцию для $lookup. Он также защищает вас, если вы когда-либо измените регистрацию вашего экземпляра mongoose.model() таким образом, чтобы изменить имя хранимой коллекции с помощью MongoDB.


Полная демонстрация

Ниже приведен отдельный список, демонстрирующий оба подхода как работу и то, как они дают одинаковые результаты:

const { Schema, Types: { ObjectId } } = mongoose = require('mongoose');

const uri = 'mongodb://localhost:27017/shopping';
const opts = { useNewUrlParser: true };

mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('debug', true);

const storeSchema = new Schema({
  name: { type: String }
});

const priceSchema = new Schema({
  price: { type: Number },
  store: { type: Schema.Types.ObjectId, ref: 'Store' }
});

const productSchema = new Schema({
  name: { type: String },
  prices: [{ type: Schema.Types.ObjectId, ref: 'Price' }]
});

const Store = mongoose.model('Store', storeSchema);
const Price = mongoose.model('Price', priceSchema);
const Product = mongoose.model('Product', productSchema);

const log = data => console.log(JSON.stringify(data, undefined, 2));

(async function() {

  try {

    const conn = await mongoose.connect(uri, opts);

    // Clean data
    await Promise.all(
      Object.entries(conn.models).map(([k, m]) => m.deleteMany())
    );

    // Insert working data

    let [StoreA, StoreB, StoreC] = await Store.insertMany(
      ["StoreA", "StoreB", "StoreC"].map(name => ({ name }))
    );


    let [PriceA, PriceB, PriceC, PriceD, PriceE, PriceF]
      = await Price.insertMany(
          [[StoreA,1],[StoreB,2],[StoreA,3],[StoreC,4],[StoreB,5],[StoreC,6]]
            .map(([store, price]) => ({ price, store }))
        );


    let [Milk, Cheese, Bread] = await Product.insertMany(
      [
        { name: 'Milk', prices: [PriceA, PriceB] },
        { name: 'Cheese', prices: [PriceC, PriceD] },
        { name: 'Bread', prices: [PriceE, PriceF] }
      ]
    );


    // Test 1
    {
      log("Single Store - expressive")
      const pipeline = [
        { '$lookup': {
          'from': Price.collection.name,
          'let': { prices: '$prices' },
          'pipeline': [
            { '$match': {
              'store': ObjectId(StoreA._id),  // demo - it's already an ObjectId
              '$expr': { '$in': [ '

Я не совсем уверен, что ваш существующий конвейер является наиболее оптимальным, но без примерных данных, которые можно использовать, трудно действительно сказать иначе. Так что просто продолжаем работать с тем, что у вас есть:

Использование $ unwind

[110]

Точки там начинаются с:

  • Initial [ 116] - не требуется. Только в очень ранних выпусках MongoDB 3.0 это когда-либо было требованием $unwind массива значений перед использованием $lookup для этих значений.

  • $unwind после $lookup - Всегда требуется, если вы ожидаете совпадения с «единичным» объектом, поскольку $lookup всегда возвращает массив. [ 1178] [тысяча сто семьдесят два]

  • $match после $unwind - фактически «оптимизация» для конвейерной обработки и фактически требование для «фильтрации» [ 1160]. Без $unwind это просто подтверждение того, что «что-то есть» , но элементы, которые не совпадают, не будут удалены.

  • $push в $group - Это фактическая часть, которая перестраивает массив "prices".

Ключевым моментом, который вы в основном упускали, было использование $first для содержимого «всего документа». Вы действительно никогда не хотите этого, и даже если вы хотите больше, чем просто "name", вы всегда хотите $push "prices".

На самом деле вам, вероятно, нужно больше полей, чем просто name из исходного документа, но на самом деле вам следует использовать вместо этого следующую форму.

Expressive $ lookup

Альтернатива доступна с большинством современных выпусков MongoDB начиная с MongoDB 3.6, которые, честно говоря, вы должны использовать как минимум:

[111]

Итак, первое, на что стоит обратить внимание Это «внешний» pipeline на самом деле является просто одной $lookup стадией, так как все, что ему действительно нужно сделать, это «присоединиться» к коллекции prices. С точки зрения присоединения к вашей исходной коллекции это также верно, поскольку дополнительный $lookup в приведенном выше примере фактически связан с prices другой коллекцией.

Это именно то, что делает эта новая форма, поэтому вместо использования $unwind в результирующем массиве, а затем после объединения, только соответствующие элементы для «цен». "затем" присоединяются "к коллекции" stores ", и перед они возвращаются в массив. Конечно, поскольку существует отношение «один к одному» с «магазином», это действительно $unwind .

Короче говоря, вывод этого просто содержит исходный документ с массивом "prices" внутри. Таким образом, нет необходимости перестраивать через $group и не путать то, что вы используете $first и что вы $push . [ 1186]


ПРИМЕЧАНИЕ : я более чем подозреваю ваше утверждение «хранилища фильтров» и пытаюсь сопоставить поле store, как представлено в коллекции "prices". Вопрос показывает ожидаемый результат из двух разных магазинов, даже если вы укажете совпадение равенства.

Если что-то подозреваю, вы могли бы означать «список магазинов» , который вместо этого был бы больше похож на:

[112]

То, как вы бы это сделали работать с «списком строк» ​​ в обоих случаях, используя $in для сопоставления со «списком» и Array.map() для работы с предоставленным списком и возвращать каждый как ObjectId() значения.

СОВЕТ : С mongoose вы используете «модель» вместо того, чтобы работать с именами коллекций, и фактические имена коллекций MongoDB обычно являются множественным числом от имени модели, которое вы зарегистрировали.

Таким образом, вам не нужно «жестко» кодировать фактические имена коллекций для $lookup, просто используйте:

[113] blockquote>

.collection.name является доступным свойством во всех моделях, и может избавить вас от необходимости помнить, как на самом деле назвать коллекцию для $lookup. Он также защищает вас, если вы когда-либо измените регистрацию вашего экземпляра mongoose.model() таким образом, чтобы изменить имя хранимой коллекции с помощью MongoDB.


Полная демонстрация

Ниже приведен отдельный список, демонстрирующий оба подхода как работу и то, как они дают одинаковые результаты:

[114]

, который выдает результат: [1194 ]

Mongoose: stores.deleteMany({}, {})
Mongoose: prices.deleteMany({}, {})
Mongoose: products.deleteMany({}, {})
Mongoose: stores.insertMany([ { _id: 5c7c79bcc78675135c09f54b, name: 'StoreA', __v: 0 }, { _id: 5c7c79bcc78675135c09f54c, name: 'StoreB', __v: 0 }, { _id: 5c7c79bcc78675135c09f54d, name: 'StoreC', __v: 0 } ], {})
Mongoose: prices.insertMany([ { _id: 5c7c79bcc78675135c09f54e, price: 1, store: 5c7c79bcc78675135c09f54b, __v: 0 }, { _id: 5c7c79bcc78675135c09f54f, price: 2, store: 5c7c79bcc78675135c09f54c, __v: 0 }, { _id: 5c7c79bcc78675135c09f550, price: 3, store: 5c7c79bcc78675135c09f54b, __v: 0 }, { _id: 5c7c79bcc78675135c09f551, price: 4, store: 5c7c79bcc78675135c09f54d, __v: 0 }, { _id: 5c7c79bcc78675135c09f552, price: 5, store: 5c7c79bcc78675135c09f54c, __v: 0 }, { _id: 5c7c79bcc78675135c09f553, price: 6, store: 5c7c79bcc78675135c09f54d, __v: 0 } ], {})
Mongoose: products.insertMany([ { prices: [ 5c7c79bcc78675135c09f54e, 5c7c79bcc78675135c09f54f ], _id: 5c7c79bcc78675135c09f554, name: 'Milk', __v: 0 }, { prices: [ 5c7c79bcc78675135c09f550, 5c7c79bcc78675135c09f551 ], _id: 5c7c79bcc78675135c09f555, name: 'Cheese', __v: 0 }, { prices: [ 5c7c79bcc78675135c09f552, 5c7c79bcc78675135c09f553 ], _id: 5c7c79bcc78675135c09f556, name: 'Bread', __v: 0 } ], {})
"Single Store - expressive"
Mongoose: products.aggregate([ { '$lookup': { from: 'prices', let: { prices: '$prices' }, pipeline: [ { '$match': { store: 5c7c79bcc78675135c09f54b, '$expr': { '$in': [ '

Я не совсем уверен, что ваш существующий конвейер является наиболее оптимальным, но без примерных данных, которые можно использовать, трудно действительно сказать иначе. Так что просто продолжаем работать с тем, что у вас есть:

Использование $ unwind

[110]

Точки там начинаются с:

  • Initial [ 116] - не требуется. Только в очень ранних выпусках MongoDB 3.0 это когда-либо было требованием $unwind массива значений перед использованием $lookup для этих значений.

  • $unwind после $lookup - Всегда требуется, если вы ожидаете совпадения с «единичным» объектом, поскольку $lookup всегда возвращает массив. [ 1178] [тысяча сто семьдесят два]

  • $match после $unwind - фактически «оптимизация» для конвейерной обработки и фактически требование для «фильтрации» [ 1160]. Без $unwind это просто подтверждение того, что «что-то есть» , но элементы, которые не совпадают, не будут удалены.

  • $push в $group - Это фактическая часть, которая перестраивает массив "prices".

Ключевым моментом, который вы в основном упускали, было использование $first для содержимого «всего документа». Вы действительно никогда не хотите этого, и даже если вы хотите больше, чем просто "name", вы всегда хотите $push "prices".

На самом деле вам, вероятно, нужно больше полей, чем просто name из исходного документа, но на самом деле вам следует использовать вместо этого следующую форму.

Expressive $ lookup

Альтернатива доступна с большинством современных выпусков MongoDB начиная с MongoDB 3.6, которые, честно говоря, вы должны использовать как минимум:

[111]

Итак, первое, на что стоит обратить внимание Это «внешний» pipeline на самом деле является просто одной $lookup стадией, так как все, что ему действительно нужно сделать, это «присоединиться» к коллекции prices. С точки зрения присоединения к вашей исходной коллекции это также верно, поскольку дополнительный $lookup в приведенном выше примере фактически связан с prices другой коллекцией.

Это именно то, что делает эта новая форма, поэтому вместо использования $unwind в результирующем массиве, а затем после объединения, только соответствующие элементы для «цен». "затем" присоединяются "к коллекции" stores ", и перед они возвращаются в массив. Конечно, поскольку существует отношение «один к одному» с «магазином», это действительно $unwind .

Короче говоря, вывод этого просто содержит исходный документ с массивом "prices" внутри. Таким образом, нет необходимости перестраивать через $group и не путать то, что вы используете $first и что вы $push . [ 1186]


ПРИМЕЧАНИЕ : я более чем подозреваю ваше утверждение «хранилища фильтров» и пытаюсь сопоставить поле store, как представлено в коллекции "prices". Вопрос показывает ожидаемый результат из двух разных магазинов, даже если вы укажете совпадение равенства.

Если что-то подозреваю, вы могли бы означать «список магазинов» , который вместо этого был бы больше похож на:

[112]

То, как вы бы это сделали работать с «списком строк» ​​ в обоих случаях, используя $in для сопоставления со «списком» и Array.map() для работы с предоставленным списком и возвращать каждый как ObjectId() значения.

СОВЕТ : С mongoose вы используете «модель» вместо того, чтобы работать с именами коллекций, и фактические имена коллекций MongoDB обычно являются множественным числом от имени модели, которое вы зарегистрировали.

Таким образом, вам не нужно «жестко» кодировать фактические имена коллекций для $lookup, просто используйте:

[113] blockquote>

.collection.name является доступным свойством во всех моделях, и может избавить вас от необходимости помнить, как на самом деле назвать коллекцию для $lookup. Он также защищает вас, если вы когда-либо измените регистрацию вашего экземпляра mongoose.model() таким образом, чтобы изменить имя хранимой коллекции с помощью MongoDB.


Полная демонстрация

Ниже приведен отдельный список, демонстрирующий оба подхода как работу и то, как они дают одинаковые результаты:

[114]

, который выдает результат: [1194 ] [115]id', '$prices' ] } } }, { '$lookup': { from: 'stores', let: { store: '$store' }, pipeline: [ { '$match': { '$expr': { '$eq': [ '

Я не совсем уверен, что ваш существующий конвейер является наиболее оптимальным, но без примерных данных, которые можно использовать, трудно действительно сказать иначе. Так что просто продолжаем работать с тем, что у вас есть:

Использование $ unwind

[110]

Точки там начинаются с:

  • Initial [ 116] - не требуется. Только в очень ранних выпусках MongoDB 3.0 это когда-либо было требованием $unwind массива значений перед использованием $lookup для этих значений.

  • $unwind после $lookup - Всегда требуется, если вы ожидаете совпадения с «единичным» объектом, поскольку $lookup всегда возвращает массив. [ 1178] [тысяча сто семьдесят два]

  • $match после $unwind - фактически «оптимизация» для конвейерной обработки и фактически требование для «фильтрации» [ 1160]. Без $unwind это просто подтверждение того, что «что-то есть» , но элементы, которые не совпадают, не будут удалены.

  • $push в $group - Это фактическая часть, которая перестраивает массив "prices".

Ключевым моментом, который вы в основном упускали, было использование $first для содержимого «всего документа». Вы действительно никогда не хотите этого, и даже если вы хотите больше, чем просто "name", вы всегда хотите $push "prices".

На самом деле вам, вероятно, нужно больше полей, чем просто name из исходного документа, но на самом деле вам следует использовать вместо этого следующую форму.

Expressive $ lookup

Альтернатива доступна с большинством современных выпусков MongoDB начиная с MongoDB 3.6, которые, честно говоря, вы должны использовать как минимум:

[111]

Итак, первое, на что стоит обратить внимание Это «внешний» pipeline на самом деле является просто одной $lookup стадией, так как все, что ему действительно нужно сделать, это «присоединиться» к коллекции prices. С точки зрения присоединения к вашей исходной коллекции это также верно, поскольку дополнительный $lookup в приведенном выше примере фактически связан с prices другой коллекцией.

Это именно то, что делает эта новая форма, поэтому вместо использования $unwind в результирующем массиве, а затем после объединения, только соответствующие элементы для «цен». "затем" присоединяются "к коллекции" stores ", и перед они возвращаются в массив. Конечно, поскольку существует отношение «один к одному» с «магазином», это действительно $unwind .

Короче говоря, вывод этого просто содержит исходный документ с массивом "prices" внутри. Таким образом, нет необходимости перестраивать через $group и не путать то, что вы используете $first и что вы $push . [ 1186]


ПРИМЕЧАНИЕ : я более чем подозреваю ваше утверждение «хранилища фильтров» и пытаюсь сопоставить поле store, как представлено в коллекции "prices". Вопрос показывает ожидаемый результат из двух разных магазинов, даже если вы укажете совпадение равенства.

Если что-то подозреваю, вы могли бы означать «список магазинов» , который вместо этого был бы больше похож на:

[112]

То, как вы бы это сделали работать с «списком строк» ​​ в обоих случаях, используя $in для сопоставления со «списком» и Array.map() для работы с предоставленным списком и возвращать каждый как ObjectId() значения.

СОВЕТ : С mongoose вы используете «модель» вместо того, чтобы работать с именами коллекций, и фактические имена коллекций MongoDB обычно являются множественным числом от имени модели, которое вы зарегистрировали.

Таким образом, вам не нужно «жестко» кодировать фактические имена коллекций для $lookup, просто используйте:

[113] blockquote>

.collection.name является доступным свойством во всех моделях, и может избавить вас от необходимости помнить, как на самом деле назвать коллекцию для $lookup. Он также защищает вас, если вы когда-либо измените регистрацию вашего экземпляра mongoose.model() таким образом, чтобы изменить имя хранимой коллекции с помощью MongoDB.


Полная демонстрация

Ниже приведен отдельный список, демонстрирующий оба подхода как работу и то, как они дают одинаковые результаты:

[114]

, который выдает результат: [1194 ] [115]id', '$store' ] } } } ], as: 'store' } }, { '$unwind': '$store' } ], as: 'prices' } }, { '$match': { 'prices.0': { '$exists': true } } } ], {}) [ { "_id": "5c7c79bcc78675135c09f554", "prices": [ { "_id": "5c7c79bcc78675135c09f54e", "price": 1, "store": { "_id": "5c7c79bcc78675135c09f54b", "name": "StoreA", "__v": 0 }, "__v": 0 } ], "name": "Milk", "__v": 0 }, { "_id": "5c7c79bcc78675135c09f555", "prices": [ { "_id": "5c7c79bcc78675135c09f550", "price": 3, "store": { "_id": "5c7c79bcc78675135c09f54b", "name": "StoreA", "__v": 0 }, "__v": 0 } ], "name": "Cheese", "__v": 0 } ] "Dual Store - expressive" Mongoose: products.aggregate([ { '$lookup': { from: 'prices', let: { prices: '$prices' }, pipeline: [ { '$match': { store: { '$in': [ 5c7c79bcc78675135c09f54b, 5c7c79bcc78675135c09f54c ] }, '$expr': { '$in': [ '

Я не совсем уверен, что ваш существующий конвейер является наиболее оптимальным, но без примерных данных, которые можно использовать, трудно действительно сказать иначе. Так что просто продолжаем работать с тем, что у вас есть:

Использование $ unwind

[110]

Точки там начинаются с:

  • Initial [ 116] - не требуется. Только в очень ранних выпусках MongoDB 3.0 это когда-либо было требованием $unwind массива значений перед использованием $lookup для этих значений.

  • $unwind после $lookup - Всегда требуется, если вы ожидаете совпадения с «единичным» объектом, поскольку $lookup всегда возвращает массив. [ 1178] [тысяча сто семьдесят два]

  • $match после $unwind - фактически «оптимизация» для конвейерной обработки и фактически требование для «фильтрации» [ 1160]. Без $unwind это просто подтверждение того, что «что-то есть» , но элементы, которые не совпадают, не будут удалены.

  • $push в $group - Это фактическая часть, которая перестраивает массив "prices".

Ключевым моментом, который вы в основном упускали, было использование $first для содержимого «всего документа». Вы действительно никогда не хотите этого, и даже если вы хотите больше, чем просто "name", вы всегда хотите $push "prices".

На самом деле вам, вероятно, нужно больше полей, чем просто name из исходного документа, но на самом деле вам следует использовать вместо этого следующую форму.

Expressive $ lookup

Альтернатива доступна с большинством современных выпусков MongoDB начиная с MongoDB 3.6, которые, честно говоря, вы должны использовать как минимум:

[111]

Итак, первое, на что стоит обратить внимание Это «внешний» pipeline на самом деле является просто одной $lookup стадией, так как все, что ему действительно нужно сделать, это «присоединиться» к коллекции prices. С точки зрения присоединения к вашей исходной коллекции это также верно, поскольку дополнительный $lookup в приведенном выше примере фактически связан с prices другой коллекцией.

Это именно то, что делает эта новая форма, поэтому вместо использования $unwind в результирующем массиве, а затем после объединения, только соответствующие элементы для «цен». "затем" присоединяются "к коллекции" stores ", и перед они возвращаются в массив. Конечно, поскольку существует отношение «один к одному» с «магазином», это действительно $unwind .

Короче говоря, вывод этого просто содержит исходный документ с массивом "prices" внутри. Таким образом, нет необходимости перестраивать через $group и не путать то, что вы используете $first и что вы $push . [ 1186]


ПРИМЕЧАНИЕ : я более чем подозреваю ваше утверждение «хранилища фильтров» и пытаюсь сопоставить поле store, как представлено в коллекции "prices". Вопрос показывает ожидаемый результат из двух разных магазинов, даже если вы укажете совпадение равенства.

Если что-то подозреваю, вы могли бы означать «список магазинов» , который вместо этого был бы больше похож на:

[112]

То, как вы бы это сделали работать с «списком строк» ​​ в обоих случаях, используя $in для сопоставления со «списком» и Array.map() для работы с предоставленным списком и возвращать каждый как ObjectId() значения.

СОВЕТ : С mongoose вы используете «модель» вместо того, чтобы работать с именами коллекций, и фактические имена коллекций MongoDB обычно являются множественным числом от имени модели, которое вы зарегистрировали.

Таким образом, вам не нужно «жестко» кодировать фактические имена коллекций для $lookup, просто используйте:

[113] blockquote>

.collection.name является доступным свойством во всех моделях, и может избавить вас от необходимости помнить, как на самом деле назвать коллекцию для $lookup. Он также защищает вас, если вы когда-либо измените регистрацию вашего экземпляра mongoose.model() таким образом, чтобы изменить имя хранимой коллекции с помощью MongoDB.


Полная демонстрация

Ниже приведен отдельный список, демонстрирующий оба подхода как работу и то, как они дают одинаковые результаты:

[114]

, который выдает результат: [1194 ] [115]id', '$prices' ] } } }, { '$lookup': { from: 'stores', let: { store: '$store' }, pipeline: [ { '$match': { '$expr': { '$eq': [ '

Я не совсем уверен, что ваш существующий конвейер является наиболее оптимальным, но без примерных данных, которые можно использовать, трудно действительно сказать иначе. Так что просто продолжаем работать с тем, что у вас есть:

Использование $ unwind

[110]

Точки там начинаются с:

  • Initial [ 116] - не требуется. Только в очень ранних выпусках MongoDB 3.0 это когда-либо было требованием $unwind массива значений перед использованием $lookup для этих значений.

  • $unwind после $lookup - Всегда требуется, если вы ожидаете совпадения с «единичным» объектом, поскольку $lookup всегда возвращает массив. [ 1178] [тысяча сто семьдесят два]

  • $match после $unwind - фактически «оптимизация» для конвейерной обработки и фактически требование для «фильтрации» [ 1160]. Без $unwind это просто подтверждение того, что «что-то есть» , но элементы, которые не совпадают, не будут удалены.

  • $push в $group - Это фактическая часть, которая перестраивает массив "prices".

Ключевым моментом, который вы в основном упускали, было использование $first для содержимого «всего документа». Вы действительно никогда не хотите этого, и даже если вы хотите больше, чем просто "name", вы всегда хотите $push "prices".

На самом деле вам, вероятно, нужно больше полей, чем просто name из исходного документа, но на самом деле вам следует использовать вместо этого следующую форму.

Expressive $ lookup

Альтернатива доступна с большинством современных выпусков MongoDB начиная с MongoDB 3.6, которые, честно говоря, вы должны использовать как минимум:

[111]

Итак, первое, на что стоит обратить внимание Это «внешний» pipeline на самом деле является просто одной $lookup стадией, так как все, что ему действительно нужно сделать, это «присоединиться» к коллекции prices. С точки зрения присоединения к вашей исходной коллекции это также верно, поскольку дополнительный $lookup в приведенном выше примере фактически связан с prices другой коллекцией.

Это именно то, что делает эта новая форма, поэтому вместо использования

задан Stephen Denne 4 November 2008 в 07:41
поделиться

2 ответа

Как Вы сказали, , addShutdownHook является способом пойти.

, НО:

  • нет никакой реальной гарантии, что Ваши рычаги завершения работы выполняются, если программа завершается. Кто-то мог уничтожить процесс Java, и в этом случае Ваш рычаг завершения работы не будет выполняться. (как сказано в этом ТАК вопрос )

  • некоторые стандартные библиотеки имеют их собственные рычаги, которые могут работать перед Вашими.

  • остерегаются мертвых блокировок.

Другая возможность была бы к , переносят Вашу программу Java в сервисе .

10
ответ дан 1 December 2019 в 13:22
поделиться

Я уже работал он сам. Я добавляю рычаг завершения работы, следующим образом:

final String[] cmd = {"<childProcessName>"};
final Process process = Runtime.getRuntime().exec(cmd);
Runnable runnable = new Runnable() {
    public void run() {
        process.destroy();
    }
};
Runtime.getRuntime().addShutdownHook(new Thread(runnable));
9
ответ дан 1 December 2019 в 13:22
поделиться
Другие вопросы по тегам:

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