如何在MongoDB的映射函数中将BSON对象转换为字符串?

5
我有一些包含字段xyz的文档。
{ term: "puppies", page: { skip: 1, per_page: 20 } } // not useful as a composite key...
{ page: { skip: 1, per_page: 20 }, term: "puppies" } // different order, same contents

为了确定xyz中的“顶部”值,我想将它们全部映射到类似以下的内容:
emit('term="puppies",page={ skip: 1, per_page: 20 }', 1); // composite key

但我无法将嵌入对象转换为有意义的字符串:

emit('term="puppies",page=[object bson_object]', 1); // not useful

有没有建议可以替代toString()函数?

# return the top <num> values of <field> based on a query <selector>
#
# example: top(10, :xyz, {}, {})
def top(num, field, selector, opts = {})
  m = ::BSON::Code.new <<-EOS
    function() {

      var keys = [];

      for (var key in this.#{field}) {
        keys.push(key);
      }

      keys.sort ();

      var sortedKeyValuePairs = [];

      for (i in keys) {
        var key = keys[i];
        var value = this.#{field}[key];

        if (value.constructor.name == 'String') {
          var stringifiedValue = value;
        } else if (value.constructor.name == 'bson_object') {
          // this just says "[object bson_object]" which is not useful
          var stringifiedValue = value.toString();
        } else {
          var stringifiedValue = value.toString();
        }

        sortedKeyValuePairs.push([key, stringifiedValue].join('='));
      }

      // hopefully we'll end up with something like
      // emit("term=puppies,page={skip:1, per_page:20}")
      // instead of
      // emit("term=puppies,page=[object bson_object]")
      emit(sortedKeyValuePairs.join(','), 1);
    }
  EOS
  r = ::BSON::Code.new <<-EOS
    function(k, vals) {
      var sum=0;
      for (var i in vals) sum += vals[i];
      return sum;
    }
  EOS
  docs = []
  collection.map_reduce(m, r, opts.merge(:query => selector)).find({}, :limit => num, :sort => [['value', ::Mongo::DESCENDING]]).each do |doc|
    docs.push doc
  end
  docs
end

直接跳到第一个代码示例。为什么它不能作为复合键使用?MongoDB 完全可以将 BSON 对象作为 _id(或键)。 - Gates VP
2个回答

7
鉴于MongoDB使用SpiderMonkey作为其内部JS引擎,您不能使用JSON.stringify(即使/当MongoDB切换到V8时也可以工作),或者SpiderMonkey的非标准toSource方法吗?(抱歉,目前无法尝试以确认它是否有效)

7
在Mongo 2.0.6中,JSON.stringify对我无效,但是obj.toSource有效。谢谢。 - Paul Wheeler
+Paul Wheeler,你应该把那个变成答案。 - Archimedes Trajano

1

toSource method可以完成这项工作,但它也会添加括号。为了使文档更加清晰,请使用:

value.toSource().substring(1, value.toSource().length - 1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接