MongoDB: сравнение полей в массиве вложенных документов без $ unwind?

Я не думаю, что кто-то объяснил здесь, что одна проблема заключается в том, что вам нужны « указатели на элементы », а не обычные указатели функций.

Указатели элементов для функций не просто указатели функций. В условиях реализации компилятор не может использовать простой адрес функции, поскольку, как правило, вы не знаете адрес для вызова, пока не узнаете, к какому объекту относится к разыменованию (думать о виртуальных функциях). Вы также должны знать объект, чтобы, конечно, предоставить неявный параметр this.

Сказав, что они вам нужны, теперь я скажу, что вам действительно нужно их избегать. Серьезно, указатели членов - это боль. Гораздо более разумно смотреть на объектно-ориентированные шаблоны проектирования, которые достигают той же цели, или использовать boost::function или что-то еще, как упомянуто выше, - если вы сделаете этот выбор, то есть.

Если вы указали на эту функцию указатель на существующий код, вам действительно нужен простой указатель на функцию, вы должны написать функцию как статический член класса. Статическая функция-член не понимает this, поэтому вам нужно передать объект в явном параметре. Когда-то была необычная идиома в этих строках для работы со старым кодом на C, которому нужны указатели на функции

class myclass
{
  public:
    virtual void myrealmethod () = 0;

    static void myfunction (myclass *p);
}

void myclass::myfunction (myclass *p)
{
  p->myrealmethod ();
}

Поскольку myfunction - действительно просто нормальная функция (проблемы с областью действия), Функциональный указатель можно найти в обычном режиме C.

EDIT - этот метод называется «метод класса» или «статическая функция-член». Основное отличие от функции, не являющейся членом, заключается в том, что если вы ссылаетесь на нее вне класса, вы должны указать область с помощью оператора разрешения области ::. Например, чтобы получить указатель на функцию, используйте &myclass::myfunction и вызовите его, используя myclass::myfunction (arg);.

Подобные вещи довольно распространены при использовании старых API Win32, которые первоначально были предназначены для C, а чем C ++. Конечно, в этом случае параметр обычно является LPARAM или аналогичным, а не указателем, и требуется некоторое литье.

1
задан user41951 18 January 2019 в 12:27
поделиться

2 ответа

db.collection.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $unwind: {
                path: "$subdocuments",

            }
        },

        // Stage 2
        {
            $addFields: {
                "subdocuments.fields_equal": {
                    $cond: {
                        if: {
                            $eq: ["$subdocuments.field1", "$subdocuments.field2"]
                        },
                        then: true,
                        else: false
                    }
                }
            }
        },

        // Stage 3
        {
            $group: {
                _id: '[110]id',
                subdocuments: {
                    $addToSet: '$subdocuments'
                }
            }
        },

    ]



);
0
ответ дан Rubin Porwal 18 January 2019 в 12:27
поделиться

Запустите эту агрегацию.

db.collection.aggregate([{
  '$addFields': {
    'subdocuments': {
      $map: {
        input: "$subdocuments",
        in: {
          $mergeObjects: [{
              fields_equal: { $eq: ["$this.field1", "$this.field2"] }
            },
            "$this"
          ]
        }
      }
    }
  }
}])
0
ответ дан Ashok 18 January 2019 в 12:27
поделиться
Другие вопросы по тегам:

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