I have an app with a very large legacy database. The model I'm currently indexing has 7,075 stories
. I'm trying to create a javascript-y way for a user to search through all the records and have them automatically filter asynchronously.
我有一个带有非常大的遗留数据库的应用程序。我目前正在索引的模型有7075个故事。我正在尝试创建一种让用户搜索所有记录并让它们自动异步过滤的javascrip-y方法。
Ideally, here's the blurb (currently a partial in stories/_blurb
that's being rendered in a Story.all.each do
block):
理想情况下,下面是格式回复信息(当前是Stories/_blurb中的一部分,呈现在Story.all.each do块中):
<div class="pb-4">
<div id="blurb<%= story.id %>" class="blurb box p-3">
<div class="text-end">
<%= render partial: "stories/badges", locals: { story: story, show_author: false } %>
</div>
<h3 class="header-font mb-0"><%= link_to story.title, story_path(story) %></h3>
<p class="mb-2 italics">
<% if story.author %>
by <%= link_to story.author.penname, author_path(story.author) %>
<% else %>
by Unknown Author
<% end %>
</p>
<p><%= simple_format(story.summary) %></p>
<p class="text-end mt-1 italics small">
<%= pluralize(story.word_count, "Words") %>,
<% if story.chapters.count != 0 %>
Started <%= story.chapters.first.created_at.strftime("%m/%d/%Y") %>,
<% else %>
Started <%= story.created_at.strftime("%m/%d/%Y") %>,
<% end %>
<% if story.chapters.count != 0 %>
Updated <%= story.chapters.last.created_at.strftime("%m/%d/%Y") %>
<% else %>
Updated <%= story.created_at.strftime("%m/%d/%Y") %>,
<% end %>
</p>
<% if @current_author == story.author %>
<div class="text-end">
<%= link_to "Edit Story", edit_story_path(story), class: "btn btn-admin btn-small" %>
<%= button_to "Delete Story", story_path(story), form: { data: { turbo_confirm: 'Are you sure you want to delete this story? This action cannot be undone.' } }, class: "btn btn-small btn-admin", :method => :delete %>
</div> <!-- author buttons -->
<% elsif @current_author %>
<div class="text-start">
<%= render partial: "story_markers/buttons_read_later", locals: { story: story } %>
<%= render partial: "story_markers/buttons_read", locals: { story: story } %>
</div>
<% end %>
</div> <!-- story blurb -->
</div>
I currently have it working using Datatables.js in a kind of hacky way (having no header and rendering the above blurb in a single-cell row) that prohibits me from using the AJAX functionality for server-side processing, which means that it takes a literal minute or two to load all 7,075 stories. After that the search/filter works like a charm, but ain't nobody got time for that....
我目前使用Datatables.js以一种老套的方式(没有标题并在单个单元格行中呈现上面的格式回复信息)使用它,这禁止我使用AJAX功能进行服务器端处理,这意味着加载所有7,075篇报道需要一到两分钟的时间。在那之后,搜索/过滤就像魔咒一样工作,但没有人有时间去做……
I have had similar loading time issues for other large datasets on this app as well (there are over 70,000 users) and pagination can only do so much when you need to be able to search.
对于这个应用程序上的其他大型数据集,我也遇到过类似的加载时间问题(有超过7万用户),而分页只能在你需要能够搜索的时候才能做到这一点。
Is there a way to speed up page loading for an index of a large dataset? I've looked at posts like this and have an API that gives a JSON of the data...but I haven't found a way to plug it in that actually accomplishes my goals.
有没有办法加快大型数据集的索引的页面加载速度?我看过这样的帖子,并且有一个API可以提供数据的JSON……但我还没有找到一种方法来插入它来真正实现我的目标。
Here's what I need:
这是我需要的:
- For the index page to load in a reasonable amount of time
- Some kind of pagination
- For the user to be able to search all the records by any information (e.g. text in
story.author
and story.summary
can be searched from the same search bar
If possible, it would be great if the above could be done asynchronously. Some tools I have seen do the thing where your search text is highlighted as you search. That would be magical, but is definitely on the "wish list" not the "must have" list.
如果可能的话,如果上述操作可以异步完成,那就太好了。我见过的一些工具可以在你搜索时突出显示你的搜索文本。这将是神奇的,但绝对是在“愿望清单”上,而不是“必须拥有”清单上。
Can anyone see a way to do this in plain Rails or do I need to start looking into Vue or Backbone or something?
有没有人能找到一种简单的方法来实现这一点,或者我需要开始研究Vue或Backbone之类的东西吗?
更多回答
Are you trying to have them search by title or by something like relevancy? Are you using keyword search or are you using filter options? You can AJAX and build the search results dynamically with JS and add something like Model.find(:all, :conditions => ['name LIKE ?', "%#{tag}%"])
to your AJAX-targeted controller action. You could also use templates and render the HTML directly in the request then just loop it into the DOM. Opensearch/Elasticsearch might help a lot with this if you are in need of full-text relevancy search.
你是想让他们按标题搜索,还是按相关性之类的东西搜索?您是在使用关键字搜索,还是在使用筛选选项?您可以使用JS动态地使用AJAX和构建搜索结果,并向针对AJAX的控制器操作添加类似Model.find(:All,:Conditions=>[‘name like?’,“%#{tag}%”])的内容。您还可以使用模板并直接在请求中呈现HTML,然后将其循环到DOM中。如果您需要全文相关性搜索,OpenSearch/Elasticearch可能会对此有很大帮助。
@KevinMaze There is one search field, but they should be able to type in keywords from thestory.title
or from inside the story.summary
or a penname from story.author.name
....so it's tricky to write a simple controller method....
@Kevin Maze只有一个搜索域,但他们应该能够从story.title中输入关键字,或者从story.摘要中输入关键字,或者从story.Auth.name中输入笔名...所以编写一个简单的控制器方法是很棘手的。
You're most likely going about this wrong - you should always be querying with some sort of pagination or limit if the size of your table is non-trivial. When performing a search you don't pull everything out and then throw the irrevant stuff away - you order the rows by relevance and use limits and paging to get a reasonable amount of rows from the database.
您很可能这样做是错误的--如果表的大小不是很小,您应该始终使用某种分页或限制来查询。在执行搜索时,您不会取出所有内容,然后丢弃不合适的内容--您可以按相关性对行进行排序,并使用限制和分页从数据库中获取合理数量的行。
No matter what indexes you have loading many thousands of model instances in Rails is going to be slow and cause memory issues.
无论你有什么索引,在Rails中加载成千上万的模型实例都会很慢,并导致内存问题。
7000 is not a large table by any means. But if you try to instantiate all the models, it will bog down. The search should be done on the server, and use turbo frames to show the responses. It's fast and responsive. The only models you should instantiate are the ones that match the search criteria.
7000无论如何都不是一张大桌子。但是,如果您尝试实例化所有模型,它将停滞不前。搜索应该在服务器上完成,并使用turbo帧来显示响应。它速度快,反应灵敏。您应该实例化的唯一模型是匹配搜索条件的模型。
我是一名优秀的程序员,十分优秀!