MongoDB в Go по отношению к JSON и BSON - PullRequest
0 голосов
/ 12 декабря 2018

Я изучаю, как использовать поддерживаемое сообществом mgo репо, связанное здесь .

Я обнаружил в этом примере , что способ запросадля некоторых частей данных, кажется, сделано через BSON (поддерживаемая сообществом версия библиотеки BSON связана здесь ):

type Person struct {
    Name      string
    Phone     string
}

c.Find(bson.M{"name": "Alice"}).All(&result)

, которая даст мне все Person с именемAlice.

Я также обнаружил, что мне не нужен BSON для выполнения этого запроса.Find() принимает любой интерфейс:

c.Find(Person{
    Name: "Alice",
    Phone: "1234",
}).All(&result)

Также будет работать, но только вернет указанный точный запрос.Если я пропущу часть структуры следующим образом:

c.Find(Person{
    Name: "Alice",
}).All(&result)

result будет пустым.


Мне кажется, что избегать BSON более интуитивно и проще.Итак, мои вопросы:

  1. Следует ли мне избегать импорта BSON?
  2. Могу ли я запросить все подходящие шаблоны без использования BSON или без указания всего интерфейса?
  3. Должен лиЯ указываю ОБА JSON и BSON ключи как в json:"name" или они взаимозаменяемы?

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Пакет mgo / bson используется для кодирования и декодирования всех команд и результатов базы данных, даже если приложение не использует пакет напрямую.

Составной литерал Person{ Name: "Alice" } возвращает значение Person споле Phone установлено на "".Кодер BSON кодирует это значение в логическое значение {"Name": "Alice", "Phone": ""}.Запрос с этим значением возвращает все документы с именем равным «Алиса» И телефоном, равным «».Очевидно, что в коллекции нет документов, соответствующих этому запросу.

Документ запроса должен иметь поле «Имя» только для запроса всех документов с именем равным «Алиса» и телефоном с любым значением или не заданным вообще.

Стоит ли избегать импорта BSON?

Нет, используйте пакет bson напрямую, когда это полезно.

Могу ли я запросить все соответствующиешаблоны без использования BSON или без указания всего интерфейса?

Тип bson.M обычно является лучшим способом построения запросов, но вы можете сделать это без него.Например, вы можете запросить все документы с именем «Алиса» следующим образом:

c.Find(struct { Name string }{Name: "Alice"}).All(&result)

Вы также можете использовать map[string]interface{}:

c.Find(map[string]interface{}{"Name": "Alice"}).All(&result)

Наконец, вы можете использовать BSONФункция «omitempty» кодировщика для пропуска пустых полей из закодированного значения.Я не рекомендую такой подход, поскольку он не позволяет запрашивать документы, у которых поле равно "".Для этого подхода измените тип структуры на следующий:

type Person struct {
    Name  string `bson:",omitempty"`
    Phone string `bson:",omitempty"`
}

Должен ли я указать ОБА ключи JSON и BSON, как в json: "name", или они взаимозаменяемы?

Они не являются взаимозаменяемыми.Укажите необходимые теги для кодера BSON и кодера JSON.

0 голосов
/ 12 декабря 2018
  1. Стоит ли избегать импорта BSON?

Я не вижу причин для этого.MongoDB (через mgo) и BSON идут рука об руку.Неважно, импортируете ли вы bson или нет, bson все равно будет использоваться под капотом (для сериализации / представления данных, отправляемых туда и обратно).

Могу ли я запросить все подходящие шаблоны без использования BSON или с указанием всего интерфейса?

Да, вы можете, если вы используете опцию omitempty при указании "bson"теги, например:

type Person struct {
    Name  string `bson:"name,omitempty"`
    Phone string `bson:"phone,omitempty"`
}

Теперь, если вы выполните запрос, подобный следующему:

err = c.Find(Person{
    Name: "Alice",
}).All(&result)

Тогда, когда значение фильтра будет маршализовано в BSON, оно будет содержать только "name"поле, потому что Phone является его нулевым значением, поэтому оно не будет маршализовано.

Конечно, использование omitempty может быть не тем, что вы хотите, когда вы делаете вставку / обновление, поэтому использование одного типа для представленияи опроса людей может быть недостаточно.Как правило, вы должны пометить Person как вы хотите представить свои данные, и вы должны использовать простые значения bson.M для запроса, или создать другую структуру, которая моделирует, как вы хотите сделать запрос.

Нужно ли указывать ОБА ключи JSON и BSON, как в json:"name", или они взаимозаменяемы?

Они не являются взаимозаменяемыми, поэтому, если указать только теги json, этоне используется (игнорируется) пакетом bson, и аналогично, если вы укажете только теги bson, пакет стандартной библиотеки encoding/json не будет их использовать.Это два разных тега, используемые для двух разных целей, используемые двумя разными библиотеками (пакетами).

Вы можете или не можете указать оба.Если вы никогда не собираетесь сериализовать свои данные в JSON, вам не нужно указывать json теги.

...