При правильной комбинации $ lookup, $ project и $ match вы можете присоединиться к нескольким таблицам по нескольким параметрам. Это связано с тем, что они могут быть связаны несколько раз.
Предположим, что мы хотим сделать следующее ( reference )
SELECT S.* FROM LeftTable S
LEFT JOIN RightTable R ON S.ID =R.ID AND S.MID =R.MID WHERE R.TIM >0 AND
S.MOB IS NOT NULL
Шаг 1: Свяжите все таблицы
, вы можете $ lookup сколько угодно таблиц.
$ lookup - по одному для каждой таблицы в запросе
$ unwind - поскольку данные денормализированы правильно, иначе они завернуты в массивы
Python code ..
db.LeftTable.aggregate([
# connect all tables
{"$lookup": {
"from": "RightTable",
"localField": "ID",
"foreignField": "ID",
"as": "R"
}},
{"$unwind": "R"}
])
Шаг 2: Определите все условные выражения
$ project: определите здесь все условные операторы и все переменные, которые вы хотите выбрать.
Python Code ..
db.LeftTable.aggregate([
# connect all tables
{"$lookup": {
"from": "RightTable",
"localField": "ID",
"foreignField": "ID",
"as": "R"
}},
{"$unwind": "R"},
# define conditionals + variables
{"$project": {
"midEq": {"$eq": ["$MID", "$R.MID"]},
"ID": 1, "MOB": 1, "MID": 1
}}
])
Шаг 3: Присоедините все условные обозначения
$ match - присоедините все условия, используя OR или AND и т. д. Их могут быть кратные ,
$ project: undefine all conditionals
Python Code ..
db.LeftTable.aggregate([
# connect all tables
{"$lookup": {
"from": "RightTable",
"localField": "ID",
"foreignField": "ID",
"as": "R"
}},
{"$unwind": "$R"},
# define conditionals + variables
{"$project": {
"midEq": {"$eq": ["$MID", "$R.MID"]},
"ID": 1, "MOB": 1, "MID": 1
}},
# join all conditionals
{"$match": {
"$and": [
{"R.TIM": {"$gt": 0}},
{"MOB": {"$exists": True}},
{"midEq": {"$eq": True}}
]}},
# undefine conditionals
{"$project": {
"midEq": 0
}}
])
Практически любая комбинация таблиц, условных обозначений и объединений может быть выполнена таким образом ,
Начиная с Go 1.11, это просто невозможно полностью выполнить в рамках _test.go
программы из-за механики HTTPS.
Однако вы можете подписать один сертификат и сгенерировать файлы server.crt
и server.key
, а затем ссылаться на них в своих программах _test.go
из локального каталога на неопределенный срок.
.crt
и .key
Это сокращенная, слегка обтекаемая версия шагов, указанных в статье Дакш-шаха «Средний», Как заставить HTTPS работать в вашей локальной разработке среда за 5 минут , которая будет работать на Mac.
В каталоге, где вы хотите файлы server.crt
и server.key
, создайте два файла конфигурации
server.csr.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[dn]
C=US
ST=RandomState
L=RandomCity
O=RandomOrganization
OU=RandomOrganizationUnit
emailAddress=hello@example.com
CN = localhost
и
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
Затем введите следующие команды в этот каталог
openssl genrsa -des3 -out rootCA.key 2048
# create a passphrase
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem -config server.csr.cnf
# enter passphrase
openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config server.csr.cnf
openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 500 -sha256 -extfile v3.ext
# enter passphrase
Наконец, заставьте вашу систему доверять сертификату, который вы использовали для подписи файлы, запустив
open rootCA.pem
Это откроет сертификат в приложении Keychain Acces, где он будет найден в разделе Сертификаты и назван localhost
. Затем, чтобы Всегда доверять ему
Примечание: Я пытался многие перестановки security add-trusted-cert
из командной строки и, несмотря на то, что он добавляет сертификат в цепочку для ключей и помечает его как «Всегда доверять», мои программы на Go просто не будут ему доверять. Только метод GUI переводит систему в состояние, в котором мои программы Go будут доверять сертификату.
Любые программы Go, которые вы запускаете локально с использованием HTTPS, теперь будут доверять серверам, которые вы запускаете с использованием server.crt
и server.key
.
Вы можете создать *httptest.Server
экземпляров, которые используют эти учетные данные с
func NewLocalHTTPSTestServer(handler http.Handler) (*httptest.Server, error) {
ts := httptest.NewUnstartedServer(handler)
cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
if err != nil {
return nil, err
}
ts.TLS = &tls.Config{Certificates: []tls.Certificate{cert}}
ts.StartTLS()
return ts, nil
}
Вот пример использования:
func TestLocalHTTPSserver(t *testing.T) {
ts, err := NewLocalHTTPSTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, client")
}))
assert.Nil(t, err)
defer ts.Close()
res, err := http.Get(ts.URL)
assert.Nil(t, err)
greeting, err := ioutil.ReadAll(res.Body)
res.Body.Close()
assert.Nil(t, err)
assert.Equal(t, "Hello, client", string(greeting))
}