如何在mongodb查询过滤器中更改日期格式和连接字符串匹配?

2024-04-19 18:03:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在根据一个条件匹配驻留在两个不同数据库中的两个集合,并为符合此条件的记录创建一个新集合。你知道吗

下面是简单的标准,但我需要一个不同的标准。你知道吗

定义

function insertBatch(collection, documents) {
  var bulkInsert = collection.initializeUnorderedBulkOp();
  var insertedIds = [];
  var id;
  documents.forEach(function(doc) {
    id = doc._id;
    // Insert without raising an error for duplicates
    bulkInsert.find({_id: id}).upsert().replaceOne(doc);
    insertedIds.push(id);
  });
  bulkInsert.execute();
  return insertedIds;
}

function moveDocuments(sourceCollection, targetCollection, filter, batchSize) {
 print("Moving " + sourceCollection.find(filter).count() + " documents from " + sourceCollection + " to " + targetCollection);
  var count;
  while ((count = sourceCollection.find(filter).count()) > 0) {
    print(count + " documents remaining");
    sourceDocs = sourceCollection.find(filter).limit(batchSize);
    idsOfCopiedDocs = insertBatch(targetCollection, sourceDocs);

    targetDocs = targetCollection.find({_id: {$in: idsOfCopiedDocs}});
  }
  print("Done!")
}

呼叫

var db2 = new Mongo("<URI_1>").getDB("analy")
var db = new Mongo("<URI_2>").getDB("clone")
var readDocs= db2.coll1
var writeDocs= db.temp_coll
var Urls = new Mongo("<URI_2>").getDB("clone").myCollection.distinct("Url" ,{})
var filter= {"Url": {$in: Urls }}
moveDocuments(readDocs, writeDocs, filter, 10932)

简而言之,我的标准是distinct"Url"字符串。相反,我希望Url + Date字符串成为我的标准。有两个问题:

  1. 在一个集合中,日期格式为ISODate("2016-03-14T13:42:00.000+0000"),而在另一个集合中,日期格式为"2018-10-22T14:34:40Z"。那么,如何使他们统一,使他们相互匹配?你知道吗
  2. 假设,我们得到了1.的一个解决方案,并且我们创建了一个新的数组,它包含连接的字符串UrlsAndDate,而不是Urls。我们如何动态创建一个类似的连接字段并在其他集合中匹配它?你知道吗

例如:(非功能代码!)你知道吗

var UrlsAndDate = new Mongo("<URI_2>").getDB("clone").myCollection.distinct("Url"+"formated_Date" ,{})
var filter= {"Url"+"formated_Date": {$in: Urls }}
readDocs.find(filter)
...and do the same stuff as above!

有什么建议吗?你知道吗

有暴力解决方案,但不可行!

问题: 我想合并2个集合mycoll&;coll1。两者都有一个字段名Url和日期。mycoll35000个文档,coll1有470万个文档(16+gb)-无法加载到m/m

Algo,使用Pymango客户端编写:

  1. 迭代mycoll
    • 创建一个src字符串“url+通用日期格式”
    • 试着在coll1中找到一个匹配项,因为coll1很大,所以我不能在m/m中加载它并将其视为字典!。所以,我一遍又一遍地重复这个集合中的每个文档。
      1. 迭代coll1
        • 创建目标字符串“url+common\u date\u format” 如果src_string==dest_string 将此文档插入名为temp\u coll的新集合 这是一个糟糕的算法,因为O(35000*4.7M),需要很长时间才能完成!。如果我可以在m/m中加载4.7M,那么运行时间将减少到O(35000),这是可行的!你知道吗

有没有其他算法的建议!你知道吗


Tags: 字符串idurlnew标准varmongocount
1条回答
网友
1楼 · 发布于 2024-04-19 18:03:41

我要做的第一件事是,如果集合还不存在,就在集合上用{url: 1, date: 1}创建复合索引。假设集合A有35k个文档,集合B有470万个文档。我们无法在内存中加载全部470万文档数据。您正在迭代内部循环中B的游标对象。我假设一旦游标对象耗尽,您将再次查询集合。你知道吗

这里有一些观察,为什么我们每次都要迭代470万个文档。我们可以只获取匹配A中每个文档的url和日期的文档,而不是获取所有470万个文档然后进行匹配。将a_doc日期转换为b_doc格式,然后进行查询,比将两者转换为公共格式要好得多,这迫使我们进行470万个文档的迭代。阅读下面的伪代码。你知道吗

a_docs = a_collection.find()
c_docs = []
for doc in a_docs:
    url = doc.url
    date = doc.date
    date = convert_to_b_collection_date_format(date)
    query = {'url': url, 'date': date}
    b_doc = b_collection.find(query)
    c_docs.append(b_doc)
c_docs = covert_c_docs_to_required_format(c_docs)
c_collection.insert_many(c_docs)

上面我们循环了超过35k个文档,并对每个文档进行筛选。考虑到我们已经创建了索引,查找需要对数时间,这似乎是合理的。你知道吗

相关问题 更多 >