简体   繁体   中英

MongoDB - finding common value count between a set of documents

I have the documents in the with the two fields and I want to find common value count between a same set (category) of rows: eg

Current data look something like this (assume in Json format):

在此处输入图片说明

I need an output like this:

在此处输入图片说明

Will be grateful for any guidance/pointers. Thanks

First, get your data in the form of an array of objects. Then, we can use the following algorithm to get what you need:

  1. Get the unique categories ["Music", "Film", "History", "Science"]
  2. Get the combinations of those categories [["Music", "Film"], ["Music", "History"], ["Music", "Science"], ["Film", "History"], ...]
  3. Create a mapping of category name to the books that are contained in that category. We can use a Set to ensure that the values are unique. The map will have the structure like {"Music": Set("A", "B"), "Film": Set("A", "B", "C"), "History": Set("C", "B"), "Science": Set("C")}
  4. Use the objects and arrays that you just created to find the duplicates between the combinations.
  5. When all is said and done, you'll have an array that has the following structure: [ [cat1, cat2, [bookInCommon1, bookInCommon2]], [cat1, cat3, [bookInCommon1, bookInCommon2]], ...]

Run the code below to see it in action. mongoData holds the data that is fetched from Mongo.

 const mongoData = [{ category: "Music", book: "A" }, { category: "Music", book: "B" },{ category: "Music", book: "A" },{ category: "Film", book: "A" },{ category: "Film", book: "A" },{ category: "Film", book: "B" },{ category: "Film", book: "C" },{ category: "Film", book: "C" },{ category: "Film", book: "A" },{ category: "History", book: "C" },{ category: "History", book: "C" },{ category: "History", book: "B" },{ category: "History", book: "B" },{ category: "Science", book: "C" },{ category: "Science", book: "C" },{ category: "Science", book: "C" }]; // Step 1: Get the categories const categories = Array.from(new Set(mongoData.map(x => x.category))); // Step 2: Get combinations of those categories const combos = []; for(let i = 0; i < categories.length - 1; i++) { let outerCat = categories[i]; for(let j = i + 1; j < categories.length; j++) { let innerCat = categories[j]; combos.push([ outerCat, innerCat ]); } } // Step 3: Map the categories to the books that they contain const catBooks = mongoData.reduce((map, entry) => { map[entry.category] = map[entry.category] || new Set(); map[entry.category] = map[entry.category].add(entry.book); return map; }, {}); // Step 4: Get the duplicate books for each combo combos.forEach((combo, index) => { const cat1 = combo[0]; const cat2 = combo[1]; const cat1BooksArr = Array.from(catBooks[cat1]); const cat2BooksSet = catBooks[cat2]; const dupes = cat1BooksArr.filter(book => { return cat2BooksSet.has(book); }); combos[index].push(dupes); // push into combos array }); // Done! Your combos array contains arrays that look like this: [cat1, cat2, [dupes]] combos.forEach(combo => { console.log("Combo: " + combo[0] + ", " + combo[1]); console.log("\\tNumber of dupes: " + combo[2].length); }); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM