Поддерживайте индексы непосредственно в MongoDB и избегайте перезаписи их приложением Rails - PullRequest
0 голосов
/ 29 мая 2018

У нас есть два приложения Rails 5, которые совместно используют кластерную MongoDB, размещенную на mlab.com .

Мы определяем наши поля / индексы с помощью моделей.Приложения не знают о полях / индексах друг друга, и они должны оставаться такими:

# app 1
class Order
  include Mongoid::Document
  field :order_number,            type: String
  belongs_to :status,             inverse_of: :orders
  index({ order_number: 1 },      { background: true })
  index({ status_id: 1 },         { background: true })
end

# app 2
class Order
  include Mongoid::Document
  field :order_number,            type: String
  field :internal_comment,        type: String
  index({ order_number: 1 },      { background: true })
  index({ internal_comment: 1 },  { background: true })
end

Имея только одно приложение, мы просто поддерживаем индексирование с помощью:

bundle exec rake db:mongoid:remove_indexes
bundle exec rake db:mongoid:create_indexes

Но это заставит каждое приложение отменять индексацию друг друга.

Можно ли создавать / удалять индексы непосредственно в MongoDB и избегать перезаписи его приложениями Rails?


Чтобы лучше понять ситуацию, рассмотрим следующую серию событий.

Сначала приложение 1 вставляет новые заказы:

# app 1
Order.collection.insert_many(
  [
    {_id:             BSON::ObjectId('5b04208483c336a17ada564c'),
      order_number:   "1",
      status_id:      BSON::ObjectId('59db682c17be4a0005eb246a')
    },
    ...
  ]
)

Здесь мы сталкиваемся с проблемами с индексацией internal_comment, поскольку индекс не зарегистрирован в обоих приложениях.

Далее приложение 2 запрашивает заказы с internal_comment.Если индексирование не будет работать должным образом, будет медленно:

# app 2
Order.collection.find(
  {
    internal_comment: { "$ne": nil }
  }
).to_a

Наконец, приложение 2 обновляет один из заказов (который был добавлен приложением 1).Я не уверен, как это влияет на индексирование полей status_id и internal_comment.

# app 2 updates the order:
Order.collection.update_one(
  {
    _id:              BSON::ObjectId('5b04208483c336a17ada564c'),
    internal_comment: "foo"
  }
)

1 Ответ

0 голосов
/ 29 мая 2018

Прежде всего, не запускайте remove_indexes.Я не делал этого ни разу за 9 лет, когда использую mongodb и mongoid.

Индексы, которые вы записываете в свою модель, используются только для задачи create_index rake и нигде больше (яМожно подумать), и мой собственный рабочий процесс заключается в создании нового индекса через консоль mongo, обычно для определения наилучшего варианта индекса (такие вещи, как порядок компонентов имеют значение в конце концов) перед добавлением его в модель для дальнейшего использования.Читайте в документах mongodb о createIndex .

...