Мои условия запроса mongodb / mongoose исключают сами себя. Вы можете помочь мне это исправить?

#node.js #mongodb #mongoose #mongodb-query

#node.js #mongodb #мангуст #mongodb-запрос

Вопрос:

Когда пользователь отправляет контент в мое node.js приложение, он вводит четыре параметра: start_date, свое имя пользователя в Facebook, текстовое содержимое и флажок, независимо от того, должен ли контент быть виден всем или только его друзьям на Facebook.

Когда пользователь выбирает контент, он может получать общедоступный контент от других пользователей и контент от своих друзей на Facebook (даже если они отправили свой контент только для своих друзей).

Я создал mongoose запрос, который корректно работает в этом сценарии. Я делаю это вот так:

 var query = Test.find({})

if(startDate != undefined) {
    var startDate = new Date(req.param('startDate'));
    query = query.where('updated_at').gte(startDate);
}

if (friends != undefined) {
        var friendsSplitted = friends.split(",");
    for(var i=0; i<friendsSplitted.length; i  ) {
        query = query.or([{ 'facebook_username': friendsSplitted[i] }]);
    }
}

query = query.where('hidden').equals(false);

if (publicFlag != undefined amp;amp; publicFlag === "true") {
    query = query.or({friends_only: false});
}
 

С помощью приведенного выше кода, когда пользователь запрашивает только контент у своих друзей (который может быть частным или общедоступным), он POST startDate , его массив friends , hidden имеет значение false и publicFlag значение false . Создается запрос:

Мангуст: тест.найти({ updated_at: { ‘$GTE для’: новая дата(«СБ, 15 окт 2011 00:00:00 по Гринвичу»)}, скрытых: ложь, ‘$или: [ { facebook_username: ‘ХХХХХХХХХХХХХХ’ }, { facebook_username: ‘YYYYYYYYYYYYYYY’ } ] }) { поля: не определено }

Пользователь также может запрашивать не только контент своих друзей (частный или общедоступный), но и общедоступный контент всех остальных. Для этого он POST startDate , его массив friends hidden , имеет значение false и publicFlag значение true. Создается запрос:

Мангуст: тест.найти({ updated_at: { ‘$GTE для’: новая дата(«СБ, 15 окт 2011 00:00:00 по Гринвичу»)}, скрытых: ложь, ‘$или: [ { facebook_username: ‘ХХХХХХХХХХХХХХ’ }, { facebook_username: ‘YYYYYYYYYYYYYYY’ }, { friends_only: ложь } ] }) { поля: не определено }

Приведенный выше код работает нормально.

Я хочу добавить еще один случай, когда пользователь может извлекать контент с определенными хэштегами. По сути, когда пользователь выбирает эту опцию, он может видеть контент других пользователей, который включает только эти хэштеги. Однако этот контент — это сообщения его друзей в fb (частные или общедоступные) и сообщения других людей (то есть общедоступные).

Для этого я подумал о добавлении этого условия в мой исходный node.js код:

 if (hashtagsInput != undefined) {
    var hashtags = hashtagsInput.split(",");

    for(var i=0; i<hashtags.length; i  ) {
    query = query.or([{ 'hashtags': hashtags[i] }]);
    }
}
 

но это решение не работает должным образом.

Когда пользователь хочет получить (частный и общедоступный) контент своих друзей и общедоступный контент других — но только тот, который содержит один из хэштегов , — он POST startDate friends использует свой массив , флаг hidden , установленный на false, publicFlag установленный на true, и массив his hashtags . Когда он это делает, он создает запрос:

Мангуст: тест.найти({ updated_at: { ‘$GTE для’: новая дата(«СБ, 15 окт 2011 00:00:00 по Гринвичу»)}, ‘$или: [ { хэштеги: ‘тест1’ }, { хэштеги: ‘test2 на’ }, { facebook_username: ‘ХХХХХХХХХХ’ }, { facebook_username: ‘YYYYYYYYYYYYYYYYYY’ }, { friends_only: ложь } ], «удаленные»: ложные }) { поля: не определено }

По сути, я хочу ограничить общий запрос только определенными хэштегами.

Этот запрос не возвращает правильные данные. Теперь я не mongoose специалист, и вчера я потратил пару часов, пытаясь разобраться в этом, но я думаю, что проблема в том, что он возвращает данные, которые либо содержат один из хэштегов, ЛИБО его автор — один из моих друзей на Facebook.

Я хотел бы исправить этот запрос так, чтобы — в случае POST хэштегов пользователя — он извлекал контент, который является общедоступным и частным для его друзей и общедоступным для всех, но только тот, который содержит хотя бы один из этих хэштегов. И когда пользователь не предоставляет хэштеги — он должен работать так, как был, извлекая весь частный и общедоступный контент своих друзей и общедоступный для всех.

Не могли бы вы, пожалуйста, помочь мне исправить мой node.js код, чтобы он создавал правильный mongoose запрос?

Ответ №1:

Приведенный ниже код будет работать так, как вы хотите

 var query= {};
query.$and = [];

// and condition on start date
if(startDate != undefined) {
    var startDate = new Date(req.param('startDate'));
    query.$and.push({"updated_at":{$gte: startDate}});
}

// and condition on hastags
if (hashtagsInput != undefined) {
    var hashtags = hashtagsInput.split(",");
    query.$and.push({"hashtags":{$in: hashtags}});
}

// and condition on hidden
query.$and.push({"hidden":false});


// creating a OR condition for facebook friends and public flag
var friend_query = {};
friend_query.$or = [];

if (friends != undefined) {
    var friendsSplitted = friends.split(",");
    friend_query.$or.push({"facebook_username":{$in: friendsSplitted}});
}

if (publicFlag != undefined amp;amp; publicFlag === "true") {
    friend_query.$or.push({friends_only: false});
}

//Merging facebook friend condition with other condition with AND operator.
query.$and.push(friend_query);


var finalquery = Test.find(query)
 

Извините, я использую для создания запроса mongodb непосредственно в формате Json, это немного отличается от того, что вы делаете. Это будет работать так, как вы упомянули, о чем идет речь.

Если это не решит вашу проблему, скажите мне.

Комментарии:

1. Спасибо, Пунит, это отлично работает, у меня просто есть один небольшой дополнительный вопрос — если я хочу передать другой параметр, например, имя пользователя, и использовать его в этом запросе, должен ли я изменить его, добавив: if (username != undefined) { query.$and.push({"username": username}) }? or is there any other specific way, such as .equals`и т. Д.?

2. Вам нужно использовать query.$и.push({«username»:username}), вы можете сделать это и другим способом, но я не знаком с методами mongoose, я также предлагаю вам напрямую изменять запросы mongodb, таким образом, вы можете создавать более сложные запросы. И, пожалуйста, если вы нашли ответ полезным, примите его как правильный ответ. 🙂

3. Огромное спасибо Puneet за вашу помощь! последний вопрос — вы писали об изменении запросов mongodb, что вы имели в виду под этим? можете ли вы привести мне небольшой пример здесь, в комментариях, что изменить на что? Спасибо!

4. Я хочу сказать, что вместо использования equal, where или метода mongoose ODM вам следует использовать запросы mongodb, вот ссылка, которую вы можете проверить docs.mongodb.com/manual/tutorial/query-documents

5. Большое вам спасибо, Пунит!