0

Below is my collection "fullclicklogs" which has many json documents:

{
            "_id" : ObjectId("58fe78dcfbe21fa7896552e8"),
            "preview" : false,
            "offset" : 0,
            "result" : {
                    "tab_name" : "People-Tab",
                    "page_name" : "PEOPLE",
                    "result_number" : "1",
                    "page_num" : "0",

            }
    }
{
             "_id" : ObjectId("58fe78dcfbe21fa7896552e9"),
            "preview" : false,
            "offset" : 0,
            "result" : {
                    "tab_name" : "People-Tab",
                    "page_name" : "PEOPLE",
                    "result_number" : "5",
                    "page_num" : "0",
}
}

I would like to add a new field "DOCRANK" in my new collection "doc_rank" where DOCRANK = page_num*25+result_number

Update: Since page_num and result_number are string, I converted them into int using the following command:

 >db.fullclicklogs.find().forEach( function (x) {
    x.result.page_num = parseInt(x.result.page_num);
    db.fullclicklogs.save(x);
    });

>db.fullclicklogs.find().forEach( function (x) {
x.result.result_number = parseInt(x.result.result_number);
db.fullclicklogs.save(x);
});

Error:

2017-04-25T11:50:54.830-0700 E QUERY    [thread1] TypeError: x.result is undefined :
@(shell):2:1
DBQuery.prototype.forEach@src/mongo/shell/query.js:501:1
@(shell):1:1
>

Below is the aggregation that I am using to get DOCRANK, but I am still getting value null in my result collection:

db.getCollection('fullclicklogs').aggregate( [
   {
      $project: {
         DOCRANK: {
            $let: {
               vars: {
                  total: { $multiply: [ "$result.page_num", 25 ] },
               },
               in: { $add: [ "$$total", "$result.result_number" ] }
            }
         }
      }
   },
   {
   $out: "doc_rank1"
   }
] )

Update:Used dot notation to fix my code. But now I am getting "$multiply only supports numeric types, not string"

Output of aggregation:

assert: command failed: {
        "ok" : 0,
        "errmsg" : "$multiply only supports numeric types, not string",
        "code" : 16555,
        "codeName" : "Location16555"
} : aggregate failed
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:16:14
assert.commandWorked@src/mongo/shell/assert.js:370:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1319:5
@(shell):1:1

2017-04-25T11:12:11.420-0700 E QUERY    [thread1] Error: command failed: {
        "ok" : 0,
        "errmsg" : "$multiply only supports numeric types, not string",
        "code" : 16555,
        "codeName" : "Location16555"
} : aggregate failed :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
doassert@src/mongo/shell/assert.js:16:14
assert.commandWorked@src/mongo/shell/assert.js:370:5
DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1319:5
@(shell):1:1

May I know what's wrong with my code? Any help is appreciated. Thanks

Rose
  • 1,490
  • 5
  • 25
  • 56
  • You should first update fields value to number for arithmetic to even work. More details here http://stackoverflow.com/questions/29487351/how-to-convert-string-to-numerical-values-in-mongodb – s7vr Apr 25 '17 at 17:01
  • I checked the link and converted the integer to string, but still getting null. Check my updated answer – Rose Apr 25 '17 at 18:07

1 Answers1

1

You need to use dot notation to access the embedded fields. result is embedded document and result_number and page_num are embedded fields.

Try

db.getCollection('fullclicklogs').aggregate( [
   {
      $project: {
         DOCRANK: {
            $let: {
               vars: {
                  total: { $multiply: [ "$result.page_num", 25 ] },
               },
               in: { $add: [ "$$total", "$result.result_number" ] }
            }
         }
      }
   },
   {
   $out: "doc_rank1"
   }
] )

More here https://docs.mongodb.com/manual/core/document/#document-dot-notation

s7vr
  • 73,656
  • 11
  • 106
  • 127
  • Thanks, Veeram. I am a newbie to MongoDB. For some reasons, my conversion from string to integer is not processed. I think that's the reason why I am getting "$multiply only supports numeric types, not string" error – Rose Apr 25 '17 at 18:22
  • Yes that makes sense. Np. `db.collectionName.save(x);` Did you replace `collectionName` with `fullclicklogs` ? – s7vr Apr 25 '17 at 18:24
  • No. Thank you for catching that. I executed those commands again and then I check my fullclicklogs collection. It is now adding a new fields in my fullclicklogs collection "page_num" : NaN, "result_number" : NaN – Rose Apr 25 '17 at 18:34
  • You are welcome. Try `x.result.page_num = parseInt(x.result.page_num);` & `x.result.result_number = parseInt(x.result.result_number);` in the js function. – s7vr Apr 25 '17 at 18:42
  • I am getting a TypeError: x.result is undefined. I have updated my question – Rose Apr 25 '17 at 18:54
  • Looks like you've some documents without `result` field. Try `if (typeof x.result != 'undefined') x.result.page_num = parseInt(x.result.page_num);` – s7vr Apr 25 '17 at 18:59
  • Thank you so much for helping me out. It worked. Have a good one. – Rose Apr 25 '17 at 19:13