Агрегация MongoDB в Морфии - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь сопоставить успешную агрегацию MongoDB с морфией, но не могу получить удовлетворительный результат.Я терплю неудачу каждый раз, но не могу понять, почему.Может быть, кто-то из вас может помочь мне правильно сформулировать агрегацию в морфии.Мой запрос MongoDB выглядит следующим образом:

db.user.aggregate([{$match: { roles: "MEMBER" }}, {$group:{_id: "$roles", sum:{$sum: "$payments.2039.amount"}}}])

Роли - это массив, и агрегация работает нормально и выводит:

{ "_id" : [ "MEMBER" ], "sum" : 100 }

Я пытался сделать это в морфию с помощью этого кода Java:

final Query<User> query = datastore.createQuery(User.class).field("roles").in(Lists.newArrayList(Role.MEMBER));
final Iterator<AggregatePayments> aggregatePayments = datastore
    .createAggregation(User.class)
    .match(query)
    .group("$roles", grouping("sum", sum("payments." + currentSeason + ".amount")))
    .out(AggregatePayments.class);

Но, к сожалению, это терпит неудачу со следующим исключением:

com.mongodb.MongoCommandException: Command failed with error 17276 (Location17276): 'Use of undefined variable: roles' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "Use of undefined variable: roles", "code" : 17276, "codeName" : "Location17276" }

Моя проблема теперь выясняет, почему это работает в MongoDB, но не в morphia.Когда я пытаюсь пропустить переменную "$" для ролей для _id в morphia, я получаю следующее исключение:

com.mongodb.MongoCommandException: Command failed with error 16996 (Location16996): 'insert for $out failed: { connectionId: 1419, err: "can't use an array for _id", code: 2, codeName: "BadValue", n: 0, ok: 1.0 }' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "insert for $out failed: { connectionId: 1419, err: \"can't use an array for _id\", code: 2, codeName: \"BadValue\", n: 0, ok: 1.0 }", "code" : 16996, "codeName" : "Location16996" }

Любая помощь приветствуется!Большое спасибо!

Использование MongoDB версии 3.6 и текущей сборки morphia 1.4-SNAPSHOT.

РЕДАКТИРОВАТЬ: Что мне действительно кажется странным, так это то, что вышеуказанный Query в MongoDB работаетно запрос, сгенерированный morphia, отсутствует.Но отредактированный вручную Запрос в MongoDB и сгенерированный морфией, похоже, близко соответствуют другому.Кто-нибудь видит какие-либо ошибки?Сгенерированный запрос выглядит следующим образом:

11040 [qtp104739310-39] DEBUG org.mongodb.driver.protocol.command  - Sending command '{ "aggregate" : "user", "pipeline" : [{ "$match" : { "roles" : { "$in" : ["MEMBER"] } } }, { "$group" : { "_id" : "$roles", "sum" : { "$sum" : "$payments.2039.amount" } } }, { "$out" : "AggregatePayments" }], "cursor" : { }, "$db" : "sua", "$readPreference" : { "mode" : "primaryPreferred" } }' with request id 19 to database sua on connection [connectionId{localValue:2, serverValue:1419}] to server localhost:27017

и выдает исключение:

com.mongodb.MongoCommandException: Command failed with error 16996 (Location16996): 'insert for $out failed: { connectionId: 1419, err: "can't use an array for _id", code: 2, codeName: "BadValue", n: 0, ok: 1.0 }' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "insert for $out failed: { connectionId: 1419, err: \"can't use an array for _id\", code: 2, codeName: \"BadValue\", n: 0, ok: 1.0 }", "code" : 16996, "codeName" : "Location16996" }

. При ручном редактировании запроса в MongoDB я также могу использовать $ group: {_ id: "Роли $".... мне кажется довольно странным ...

1 Ответ

0 голосов
/ 24 мая 2018

Я не узнал разницу между методами "out ()" и "aggregate ()" в morphia.«out ()» изменяет коллекцию в хранилище MongoDB, которая не была предназначена.Использование «aggregate ()» теперь решило все проблемы:

final Query<User> query = datastore.createQuery(User.class).field("roles").in(Lists.newArrayList(Role.MEMBER));
final Iterator<AggregatePayments> aggregatePayments = datastore
    .createAggregation(User.class)
    .match(query)
    .group("roles", grouping("sum", sum("payments." + currentSeason + ".amount")))
    .aggregate(AggregatePayments.class);

Теперь работает, как и ожидалось, с morphia 1.4.0-SNAPSHOT (последняя сборка из git master) и MongoDB 3.6.

...