@IceDevil
На пути от верстки до фронта

Как сравнить значения массива в документах mongo и найти совпавшие?

Есть в монго коллекция с документами в виде
{
  _id: id,
  name: name,
  articles: [id1, id2, id3, id4]
}


К примеру на сервер на nodejs пришли id трех таких документов, как мне сравнить массивы articles этих трех документов и найти в них все совпавшие id между друг-другом?

К сожалению очень плохо знаком с синтаксисом монго, и не получается самостоятельно разобрать как написать, но догадываюсь что мне нужно что-то типа этого https://stackoverflow.com/questions/30646534/how-t...

Буду рад любой помощи, спасибо!
  • Вопрос задан
  • 469 просмотров
Решения вопроса 1
@IceDevil Автор вопроса
На пути от верстки до фронта
В итоге сам разобрал ошибку, возможно кому пригодится решение

Nodejs + Mongo + Mongoose

К примеру - Есть набор статей, у каждой статьи есть несколько тематических тегов.

Требуется сделать сортировку по несколько одновременно выбранным тегам

Решение: при создании статьи добавляем к ней тематические теги. На беке к каждому указанному тегу, добавляем id созданой статьи
Теперь у каждого тега в базе есть массив с id всех статей с этим тегом

Что бы получить все статьи содержащие несколько выбранных тегов
Нам надо найти эти теги в базе, и найти в их массивах статей, все совпадающие id

// пример документа Тега
{
	_id: "5b93e8a9c2c6bf1cd44144a0",
	name: name,
	articles: [
	  	'5b93e843c2c6bf1cd4414490',
      	'5b93e849c2c6bf1cd4414491',
      	'5b93e84dc2c6bf1cd4414492',
      	'5b93e852c2c6bf1cd4414493',
      	'5b93e857c2c6bf1cd4414494',
      	'5b93e85dc2c6bf1cd4414495',
      	'5b93e862c2c6bf1cd4414496',
      	'5b93e867c2c6bf1cd4414497',
	]
}


// для примера это id тегов в базе получиные с клиента на бек
var tagsID [
	'5b93e8a9c2c6bf1cd44144a0',
	'5b93e8b4c2c6bf1cd44144a1',
	'5b93e8bac2c6bf1cd44144a2',
	'5b93e8c0c2c6bf1cd44144a3',
	'5b93e8c6c2c6bf1cd44144a4',
]


// https://stackoverflow.com/questions/30646534/how-to-find-set-intersection-of-sets-between-the-documents-in-a-single-collectio
// тут был описан код сортировки, и моя проблема была в том, что надо было преобразовать id тегов для mongoose
var convertTagsForAggregate = [];
for (var i = 0; i < tagsID.length; i++) {
	convertTagsForAggregate.push(mongoose.Types.ObjectId(tagsID[i]))
}

Tags.aggregate([
	{
		"$match": {
			"_id": { "$in": convertTagsForAggregate}
		}
	},
	{
		"$group": {
			"_id": 0,
			"sets": { "$push": "$articles" }, // articles - название ключа массива с id статей
			"initialSet": { "$first": "$articles" }  // articles - название ключа массива с id статей
		}
	},
	{
		"$project": {
			"commonSets": {
				"$reduce": {
					"input": "$sets",
					"initialValue": "$initialSet",
					"in": { "$setIntersection": ["$$value", "$$this"] }
				}
			}
		}
	}
], function (err, result) {
	console.log(result)
})
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Если делать одним запросом, то примерно так:
// 1,2,3,10 - список идентификаторов
db.collection.find({$where: "[1,2,3,10].filter(id => (this.articles.map(id => '' + id).indexOf(id) != -1)).length > 0"})

такой запрос будет медленным

Или по одному ид:
// 10 - ид записи
db.collection.find({$where: "this.articles.map(id => '' + id).indexOf(10) != -1"})
Ответ написан
VladimirAndreev
@VladimirAndreev
php web dev
_id пришли? Так получите их из mongo и сравните на клиенте. Так, скорее всего, получится даже быстрее, чем в самой монго
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы