您的问题与解析 JSON 或 Ruby(Regexp)有关,而不是与 BSON 有关。您最初的问题直接跳到 BSON 会引起混淆。使用当前的 Ruby 驱动程序,BSON 不直接暴露给应用程序编写者,而是尽可能自然地映射到 Ruby 对象和映射到 Ruby 对象。
JSON 受到严格限制且解析安全。为 Regexp 添加解析超出了此范围。
你可以使用 Kernel#eval 不安全地做你想做的事。这将解析您的 Regexp,但它也会解析 exec、system、反引号等。对于具有任意用户输入的公共应用程序,您必须做一些更安全的事情。
另请注意,以下行之间的差异突出了 Ruby 和 MongoDB 的语义:
{ interests: [ 'fishing', 'golf' ] }
如果它们完全是 ['fishing', 'golf'],则上述内容完全匹配兴趣。没有更多,没有更少,没有其他顺序。
{ interests: { '$in' => [ 'fishing', 'golf' ] } }
如果兴趣有“钓鱼”或“高尔夫”、任何顺序、任何位置、任何额外内容,则上述匹配兴趣。请注意,字符串键 '$in' 需要原始 => 语法。
希望这有助于您的理解,请随时跟进澄清问题。
以下是一个工作示例。
我的应用程序.rb
require 'sinatra'
require 'mongo'
require 'json'
include Mongo
db = MongoClient.new().db('test')
get '/' do
if request[:query]
query = eval CGI::unescape(request[:query])
docs = db.collection('test_collection').find(query).to_a.to_json
"docs=#{docs}"
end
end
myapp_test.rb
require 'myapp'
require 'test/unit'
require 'rack/test'
require 'open-uri'
ENV['RACK_ENV'] = 'test'
class MyAppTest < Test::Unit::TestCase
include Rack::Test::Methods
def setup
@db ||= Mongo::MongoClient.new['test']
@coll ||= @db['test_collection']
@coll.remove
@coll.insert({name: 'john doe', interests: [ 'fishing', 'golf' ]})
end
def app
Sinatra::Application
end
def query_test(query)
uri = "http://localhost:4567/?query=#{URI::encode(query)}"
puts "uri=#{uri}"
get uri
puts last_response.body
assert_match(/^docs=/, last_response.body)
end
def test_john_doe
query_test("{ name: 'john doe'}")
end
def test_regexp
query_test("{ name: /.*john.*/, interests: [ 'fishing', 'golf' ]}")
end
end
红宝石-I。myapp_test.rb
Run options:
# Running tests:
uri=http://localhost:4567/?query=%7B%20name:%20/.*john.*/,%20interests:%20[%20'fishing',%20'golf'%20]%7D
docs=[{"_id":{"$oid": "50e9e60029daeb0be1000001"},"name":"john doe","interests":["fishing","golf"]}]
.uri=http://localhost:4567/?query=%7B%20name:%20'john%20doe'%7D
docs=[{"_id":{"$oid": "50e9e60129daeb0be1000002"},"name":"john doe","interests":["fishing","golf"]}]
.
Finished tests in 0.065822s, 30.3850 tests/s, 60.7700 assertions/s.
2 tests, 4 assertions, 0 failures, 0 errors, 0 skips