Rails Mongoid的`pluck`等价方法是什么?

3
在我的Rails应用程序中,我使用MongoID和Elasticsearch river进行文本搜索。
对于@devices_with_config = ConfigTextSearch.search params[:device_id],我想要提取查询匹配记录中的device_id字段。在mongoID 3.1.0中,我可以使用Band.all.pluck(:name)。但不幸的是,我卡在了3.0.23。
我看到有一个类似的moped表达式collections[:bands].find.select(name: 1),但我是Rails新手,无法弄清楚如何在控制器或模型中使用moped表达式。
有什么想法可以只提取MongoId中与"device_id"字段匹配的内容吗?
6个回答

3

1
你可以这样获取一个Moped集合
 Band.collection.find.select(name: 1)

谢谢。使用ConfigTextSearch.search("foo").find.select(device_id: 1),我得到了ArgumentError: wrong number of arguments (1 for 0) from (pry):46:in select'`的错误提示。 - dman
1
ConfigTextSearch.search("foo") 对我来说看起来不像是一个摩托车集合。 - Sergio Tulentsev
它正在使用 elasticsearch-rails,它继承了 MongoId 的方法。 - dman
1
没有与 Elasticsearch 协同工作,所以在这里你只能自己解决了,抱歉 :) - Sergio Tulentsev

1

在mongoid中,pluck方法的等价方法为:

plucked_array = User.where(:name => 'xyz').map(&: field_to_be_plucked)

其中field_to_be_plucked是需要从数组中提取值的字段名称。


2
这会从mongodb加载整个文档(以及嵌入的文档),效率相当低下。如果你被迫使用 map,更好的实现方式是:User.where(name: 'xyz').only(:email).map(&:email),这将只加载你正在查看的一个字段 :) - Jay

1

看起来你并没有使用正确的方法构建 Mongoid 的查询条件,但我没有研究过 elasticsearch-rails,所以不能百分之百确定。

如果你完全无法升级到3.1.0版本,你可以尝试直接在代码中进行修改。

module Mongoid
  class Criteria
    # select specific fields from collection based on current scope, returned as a hash
    def pluck(*fields)
      raise ArgumentError, 'Call this with at least one field' if fields.empty?

      collection.find(self.selector).select(Hash[fields.map { |field| [field, 1] }]).to_a
    end
  end
end

在添加上述代码之后,您应该能够执行以下操作:
Band.where(name: 'awesome').pluck(:id, :device_id)

0

我在同样的目的下使用了 Mongoid 3.0:

Band.all.distinct(:name)

警告:仅在所有名称不同(或者您想要删除重复项)时才相关。


这真的没有回答问题。 - Daniel Wisehart
我不同意。这个解决方案是可行的(但有我所警告的限制)。在我看来,与在内存中迭代行(例如使用map())的解决方案相比,它似乎更可取。 - Brilnius

0

找到了...据我所知,这不在MongoId文档中...

sue = bob.results.map { |r| r._source.device_id }


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