У меня есть 4 таблицы:
ForumPost
ForumReply
ForumComment
SearchTerms
Связь между таблицами :
![Please review this image](https://i.stack.imgur.com/RRBMj.jpg)
Поля таблицы SearchTerms :
objectId
ACL
SearchString
: этот столбец содержит строку или связанный объект (ForumPost, ForumComment, ForumReply), который мы будем использовать для поиска в этом столбце любой объект или связанная таблица objectTypeName
: содержит имя таблицы ссылок (ForumPost, ForumComment, ForumReply) connectedObjectId
: содержит идентификатор объекта связанного объекта из таблицы ForumPost, ForumComment , ForumReply
Поля таблицы ForumPost:
objectId
replies
: (Array) Это поле содержит объект всего ForumReply
в массиве (образец прилагается) ACL
title
description
//Sample of replies column
[
{
"__type": "Pointer",
"className": "ForumReply",
"objectId": "LSVO4KwHxO"
},
{
"__type": "Pointer",
"className": "ForumReply",
"objectId": "EQA9Fotvp5"
},
{
"__type": "Pointer",
"className": "ForumReply",
"objectId": "smpfWT8fbq"
}
]
Поля таблицы ForumReply:
objectId
text
: описание ответа to
: указатель ForumPost
таблица searchTerm
: указатель searchTerms
таблица comments
: (Массив) Это поле содержит объект всего ForumComment
в массиве (образец прилагается)
//Sample of comments field
<pre><code>[
{
"__type": "Pointer",
"className": "ForumComment",
"objectId": "FQwqHdVX7I"
}
</code>
]
Поля таблицы ForumComment:
objectId
text
: Описание ответа to
: Это указатель ForumReply
таблица searchTerm
: это указатель searchTerms
таблица
Какова моя цель : у меня есть веб-форма, где пользователь вводит строку поиска Я хочу, чтобы все ForumPost
, у кого есть эта строка. Поиск также будет применяться в ForumnReply
и ForumComments
. Таким образом, сообщения, чьи ответы и комментарии содержат строку, также будут в результате.
Что я сделал: : Сначала я запускаю поиск в таблице SearchTerms
(потому что в этой таблице есть строка поиска всех таблицы ForumPost, ForumReply, ForumComment, так что теперь у меня есть идентификаторы всех соответствующих объектов (ForumPost, ForumComment, ForumReply). После этого я попытался использовать запрос OR
с результирующими идентификаторами (используя containedIn
), а также попытался использовать Aggregates
, но никто не возвращает все соответствующие сообщения.
Пожалуйста, предложите, если есть лучший способ выполнить этот сложный поиск.
Вот мой код:
Parse.Cloud.define("searchForumPosts", function(request, response) {
isRequestLegitimate(request).then(function(result) {
if (result.legitimateRequest) {
var query = new Parse.Query("ForumPost");
var completeLength = 0;
findTextInSearchTerms(query, request.params.wildcard, "searchTerms").then(function(ids) {
var query2 = new Parse.Query("ForumPost");
if ((ids == -1 || ids.length == 0)) {
completeLength = 0;
return [];
} else {
completeLength = ids.length;
// not very efficient, if the wildcard is empty we still ask for findTextInSearchTerms, change that later on
query2.containedIn("objectId", ids);
if (request.params.pageSize && request.params.pageNumber) {
var pageSize = parseInt(request.params.pageSize);
var pageNumber = parseInt(request.params.pageNumber);
query2.limit(pageSize);
if (pageNumber > 1) {
query2.skip((pageNumber - 1) * pageSize);
}
}
// query2.include("offer");
// query2.include("offer.artist");
query2.include("creator");
query2.descending("createdAt");
query2.select("objectId", "offer","postDeleted", "title", "text", "creator", "creator.firstname", "creator.lastname", "replies");
return query2.find({
useMasterKey: true
});
}
}, function(error) {
return error;
}).then(function(foundPosts) {
console.log('foundPosts',foundPosts);
if (foundPosts.length > 1) {
var sortBy = request.params.sortBy;
if (sortBy == "artist") {
foundPosts.sort(function(a, b) {
console.log('foundPosts a',a);
console.log('foundPosts b',b);
var nameA = 'ZZZZZZZZZ';
var nameB = 'ZZZZZZZZZ';
if (a.offer) {
nameA = ((a.offer || {}).artist || {}).lastname.toUpperCase();
}
if (b.offer) {
nameB = ((b.offer || {}).artist || {}).lastname.toUpperCase();
}
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
} else if (sortBy == "author") {
foundPosts.sort(function(a, b) {
var nameA = 'ZZZZZZZZZ';
var nameB = 'ZZZZZZZZZ';
if (a.offer) {
nameA = ((a.offer || {}).creator || {}).lastname.toUpperCase();
}
if (b.offer) {
nameB = ((b.offer || {}).creator || {}).lastname.toUpperCase();
}
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
}
}
console.log('foundPostsfoundPosts',foundPosts);
var results = {};
results.completeLength = completeLength;
results.posts = foundPosts;
response.success(results);
}, function(error) {
response.error(error);
});
} else {
response.error("You must be logged in!");
}
});
});
function findTextInSearchTerms(motherQuery, wildcard, pattern, objectType) {
console.log('#findTextInSearchTerms Woldcard',wildcard);
console.log('#findTextInSearchTerms motherQuery',motherQuery);
console.log('#findTextInSearchTerms pattern',pattern);
console.log('#findTextInSearchTerms objectType',objectType);
var orQuery = null;
var promise = new Parse.Promise();
var searchTermArray = null;
var isArray = false;
var searchNeeded = true;
var filteredWildcard = []
console.log('#findTextInSearchTerms Woldcard',wildcard);
console.log('#findTextInSearchTerms motherQuery',motherQuery);
if (Array.isArray(wildcard)) {
isArray = true;
searchTermArray = wildcard
} else {
var lowerCase = (wildcard || '').toLowerCase();
lowerCase = lowerCase.trim();
// wildcard.replace(/[^a-zA-Z0-9]/g, "")
lowerCase = lowerCase.replace(/[^\w\s]/gi, '');
searchTermArray = lowerCase.split(" ");
}
if (wildcard.length < 2 && isArray == false) {
searchNeeded = false;
}
for (const element of searchTermArray) {
if((element.trim()).length > 1){
filteredWildcard.push(element);
}
}
console.log('filteredWildcard',filteredWildcard);
wildcard = filteredWildcard;
if (searchNeeded) {
console.log('#findTextInSearchTerms inside searchNeeded',wildcard);
console.log('#findTextInSearchTerms inside searchTermArray',searchTermArray);
//motherQuery.matches(pattern, regex);
if (searchTermArray.length == 1) {
console.log('#findTextInSearchTerms length == 1');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
orQuery = Parse.Query.or(query1);
} else if (searchTermArray.length == 2) {
console.log('#findTextInSearchTerms length == 2');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
var query2 = new Parse.Query("SearchTerms");
query2.contains("searchString", searchTermArray[1]);
orQuery = Parse.Query.or(query1, query2);
} else if (searchTermArray.length == 3) {
console.log('#findTextInSearchTerms length == 3');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
var query2 = new Parse.Query("SearchTerms");
query2.contains("searchString", searchTermArray[1]);
var query3 = new Parse.Query("SearchTerms");
query3.contains("searchString", searchTermArray[2]);
orQuery = Parse.Query.or(query1, query2, query3);
} else if (searchTermArray.length == 4) {
console.log('#findTextInSearchTerms length == 4');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
var query2 = new Parse.Query("SearchTerms");
query2.contains("searchString", searchTermArray[1]);
var query3 = new Parse.Query("SearchTerms");
query3.contains("searchString", searchTermArray[2]);
var query4 = new Parse.Query("SearchTerms");
query4.contains("searchString", searchTermArray[3]);
orQuery = Parse.Query.or(query1, query2, query3, query4);
} else if (searchTermArray.length == 5) {
console.log('#findTextInSearchTerms length == 5');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
var query2 = new Parse.Query("SearchTerms");
query2.contains("searchString", searchTermArray[1]);
var query3 = new Parse.Query("SearchTerms");
query3.contains("searchString", searchTermArray[2]);
var query4 = new Parse.Query("SearchTerms");
query4.contains("searchString", searchTermArray[3]);
var query5 = new Parse.Query("SearchTerms");
query5.contains("searchString", searchTermArray[4]);
orQuery = Parse.Query.or(query1, query2, query3, query4, query5);
} else if (searchTermArray.length == 6) {
console.log('#findTextInSearchTerms length == 6');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
var query2 = new Parse.Query("SearchTerms");
query2.contains("searchString", searchTermArray[1]);
var query3 = new Parse.Query("SearchTerms");
query3.contains("searchString", searchTermArray[2]);
var query4 = new Parse.Query("SearchTerms");
query4.contains("searchString", searchTermArray[3]);
var query5 = new Parse.Query("SearchTerms");
query5.contains("searchString", searchTermArray[4]);
var query6 = new Parse.Query("SearchTerms");
query6.contains("searchString", searchTermArray[5]);
orQuery = Parse.Query.or(query1, query2, query3, query4, query5, query6);
} else if (searchTermArray.length == 7) {
console.log('#findTextInSearchTerms length == 7');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
var query2 = new Parse.Query("SearchTerms");
query2.contains("searchString", searchTermArray[1]);
var query3 = new Parse.Query("SearchTerms");
query3.contains("searchString", searchTermArray[2]);
var query4 = new Parse.Query("SearchTerms");
query4.contains("searchString", searchTermArray[3]);
var query5 = new Parse.Query("SearchTerms");
query5.contains("searchString", searchTermArray[4]);
var query6 = new Parse.Query("SearchTerms");
query6.contains("searchString", searchTermArray[5]);
var query7 = new Parse.Query("SearchTerms");
query7.contains("searchString", searchTermArray[6]);
orQuery = Parse.Query.or(query1, query2, query3, query4, query5, query6, query7);
} else if (searchTermArray.length == 8) {
console.log('#findTextInSearchTerms length == 8');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
var query2 = new Parse.Query("SearchTerms");
query2.contains("searchString", searchTermArray[1]);
var query3 = new Parse.Query("SearchTerms");
query3.contains("searchString", searchTermArray[2]);
var query4 = new Parse.Query("SearchTerms");
query4.contains("searchString", searchTermArray[3]);
var query5 = new Parse.Query("SearchTerms");
query5.contains("searchString", searchTermArray[4]);
var query6 = new Parse.Query("SearchTerms");
query6.contains("searchString", searchTermArray[5]);
var query7 = new Parse.Query("SearchTerms");
query7.contains("searchString", searchTermArray[6]);
var query8 = new Parse.Query("SearchTerms");
query8.contains("searchString", searchTermArray[7]);
orQuery = Parse.Query.or(query1, query2, query3, query4, query5, query6, query7, query8);
} else if (searchTermArray.length == 9) {
console.log('#findTextInSearchTerms length == 9');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
var query2 = new Parse.Query("SearchTerms");
query2.contains("searchString", searchTermArray[1]);
var query3 = new Parse.Query("SearchTerms");
query3.contains("searchString", searchTermArray[2]);
var query4 = new Parse.Query("SearchTerms");
query4.contains("searchString", searchTermArray[3]);
var query5 = new Parse.Query("SearchTerms");
query5.contains("searchString", searchTermArray[4]);
var query6 = new Parse.Query("SearchTerms");
query6.contains("searchString", searchTermArray[5]);
var query7 = new Parse.Query("SearchTerms");
query7.contains("searchString", searchTermArray[6]);
var query8 = new Parse.Query("SearchTerms");
query8.contains("searchString", searchTermArray[7]);
var query9 = new Parse.Query("SearchTerms");
query9.contains("searchString", searchTermArray[8]);
orQuery = Parse.Query.or(query1, query2, query3, query4, query5, query6, query7, query8, query9);
} else if (searchTermArray.length >= 10) {
console.log('#findTextInSearchTerms length == 10');
var query1 = new Parse.Query("SearchTerms");
query1.contains("searchString", searchTermArray[0]);
var query2 = new Parse.Query("SearchTerms");
query2.contains("searchString", searchTermArray[1]);
var query3 = new Parse.Query("SearchTerms");
query3.contains("searchString", searchTermArray[2]);
var query4 = new Parse.Query("SearchTerms");
query4.contains("searchString", searchTermArray[3]);
var query5 = new Parse.Query("SearchTerms");
query5.contains("searchString", searchTermArray[4]);
var query6 = new Parse.Query("SearchTerms");
query6.contains("searchString", searchTermArray[5]);
var query7 = new Parse.Query("SearchTerms");
query7.contains("searchString", searchTermArray[6]);
var query8 = new Parse.Query("SearchTerms");
query8.contains("searchString", searchTermArray[7]);
var query9 = new Parse.Query("SearchTerms");
query9.contains("searchString", searchTermArray[8]);
var query10 = new Parse.Query("SearchTerms");
query10.contains("searchString", searchTermArray[9]);
orQuery = Parse.Query.or(query1, query2, query3, query4, query5, query6, query7, query8, query9, query10);
}
console.log('#findTextInSearchTerms searchTermArray', searchTermArray);
console.log('#findTextInSearchTerms orQuery', orQuery);
if (typeof(objectType) != typeof(undefined)) {
orQuery.equalTo("objectTypeName", objectType);
}
console.log('#findTextInSearchTerms objectType after');
motherQuery.matchesQuery(pattern, orQuery);
motherQuery.limit(1000);
motherQuery.find({
useMasterKey: true
}).then(function(idArray) {
console.log('#findTextInSearchTerms idArray', idArray);
//sort objects by number of occurence
var sortedIds = idArray.map(function(obj) {
return obj.id;
});
// maybe upgrade the suggestions later...
//_.chain(idArray)
/*.countBy(function (i) {
return i.id
})
.pairs()
.sortBy(function (c) {
return -c[1]
})
.map(function (c) {
return c[0]
})
.value();
*/
promise.resolve(sortedIds);
}, function(savedObject, error) {
console.log('findTextInSearchTerms savedObject',savedObject);
console.log(' findTextInSearchTerms error',error);
promise.reject(error);
});
} else {
console.log('Inside Else of #findTextInSearchTerms');
motherQuery.limit(1000);
motherQuery.find({
useMasterKey: true
}).then(function(idArray) {
var sortedIds = idArray.map(function(obj) {
return obj.id;
});
//sort objects by number of occurence
/*var sortedIds = _.chain(idArray)
.countBy(function (i) {
return i.id
})
.pairs()
.sortBy(function (c) {
return -c[1]
})
.map(function (c) {
return c[0]
})
.value();*/
promise.resolve(sortedIds);
});
}
return promise;
}