Как сравнить документы в одной коллекции? - PullRequest
2 голосов
/ 13 февраля 2020

Я новичок, когда дело доходит до понедельника go, поскольку я традиционно работал только с базой данных Oracle. У меня есть база данных mon go, в которой хранятся данные битового сегмента в столбцах, например:

_id | _class | collectorItemId| firstEverCommit | scmUrl | scmBranch | scmAuthor | scmCommitTimestamp

Там есть еще несколько столбцов, которые я пропустил ради времени. Для столбца scmBranch столбец заполняется одной из двух строк: «master» или «velop ». Вот пример того, как выглядят данные: enter image description here

Вот представление документа одной из строк:

{
"_id" : ObjectId("5e39d6a0330c130006a042c6"),
"collectorItemId" : ObjectId("5e33a6b9887ef5000620a0c0"),
"firstEverCommit" : false,
"scmUrl" : "sampleRepo1",
"scmBranch" : "master",
"scmRevisionNumber" : "a2ad6842468eb55bffcbe7d700b6addd3eb11629",
"scmAuthor" : "son123",
"scmCommitTimestamp" : NumberLong(1580841662000)
}

Я сейчас пытаюсь чтобы сформулировать mon go запросов, которые получат следующие данные:

 1. For each scmUrl, If max(scmCommitTimestamp) where scmBranch =
    "develop" > max(scmCommitTimestamp) where scmBranch = "master" THEN
    count the number of rows (i.e commits) where scmBranch = "develop"
    AND scmCommitTimestamp > max(scmCommitTimestamp) where scmBranch =
    "master"

 2. For the results found in #1, find the oldest commit and newest
    commit

На данный момент лучший запрос mon go, который мне удалось найти, следующий:

db.bitbucket.aggregate([{
    "$group": {
        "_id": {
            "scmUrl": "$scmUrl",
            "scmBranch": "$scmBranch"
        },
        "MostRecentCommit": {
            "$max": {"$toDate":"$scmCommitTimestamp"}
        }
    }
},{
    "$project": {
        "RepoName": {"$substr": ["$_id.scmUrl",39,-1]},
        "Branch": "$_id.scmBranch",
        "MostRecentCommit": "$MostRecentCommit"
    }
},{
   "$sort":{
       "RepoName":1,
       "Branch":1
       }

}
])

Но это возвращает мне только самый последний коммит для ветви разработки и основной ветки каждого scmUrl (т.е. репо), например: enter image description here

В идеале я хотел бы получить таблицу результатов со следующими столбцами:

scmUrl/RepoName | Number of commits on develop branch that are not on master branch| oldest commit in develop branch that's not in master branch | newest commit in develop branch that's not in master branch

Как мне изменить мой запрос mon go для извлечения нужных мне данных?

1 Ответ

1 голос
/ 15 февраля 2020

Вы можете попробовать что-то вроде этого.

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

db.bitbucket.aggregate([
  {"$match":{"scmBranch":"master"}},
  {"$group":{"_id":"$scmUrl","recentcommitdate":{"$max":"$scmCommitTimestamp"}}},
  {"$lookup":{
   "from":"bitbucket",
    "let":{"scmUrl":"$_id","recentcommitdate":"$recentcommitdate"},
    "pipeline":[
      {"$match":{"$expr":
        {"$and":[
          {"$eq":["$scmBranch","develop"]},
          {"$eq":["$scmUrl","$$scmUrl"]},
          {"$gte":["$scmCommitTimestamp", "$$recentcommitdate"]}
        ]}
      }},
      {"$sort":{"scmCommitTimestamp":-1}}
    ],
  "as":"commits"
  }},
  {"$match":{"commits.0":{"$exists":true}}},
  {"$project":{
     "commits":{"$size":"$commits"},
     "lastcommit":{"$arrayElemAt":["$commits",0]},
     "firstcommit":{"$arrayElemAt":["$commits",-1]}
  }}
])

Образец добавлен здесь https://mongoplayground.net/p/wLnFY0H_nJz

Обновление идентификаторов ревизий

db.bitbucket.aggregate([
  {"$match":{"scmBranch":"master"}},
  {"$group":{"_id":"$scmUrl","revisionIds":{"$push":"$scmRevisionNumber"}}},
  {"$lookup":{
   "from":"bitbucket",
    "let":{"scmUrl":"$_id","revisionIds":"$revisionIds"},
    "pipeline":[
      {"$match":{"$expr":
        {"$and":[
          {"$eq":["$scmBranch","develop"]},
          {"$eq":["$scmUrl","$$scmUrl"]},
          {"$not":[{"$in":["$scmRevisionNumber","$$revisionIds"]}]}
        ]}
      }},
      {"$sort":{"scmCommitTimestamp":-1}}
    ],
  "as":"commits"
  }},
  {"$match":{"commits.0":{"$exists":true}}},
  {"$project":{
     "commits":{"$size":"$commits"},
     "lastcommit":{"$arrayElemAt":["$commits",0]},
     "firstcommit":{"$arrayElemAt":["$commits",-1]}
  }}
])
...