keywordsuche (objective C; parse.com)

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • keywordsuche (objective C; parse.com)

    Hallo,

    Ich versuche gerade eine keywordsuche einzubauen. Als Datenbank nutze ich parse.com. So soll es funktionieren:

    In einer Klasse gibt es Objekte, die ein Array mit Keywords besitzen. Nun sucht der Nutzer mit 4 Wörtern. Dann muss er im Ergebnis zuerst das sehen, was am besten passt, also wo zum beispiel alle 4 Wörter enthalten sind, dann 3...
    Ich weiß aber leider nicht wie ich das realisieren könnte. Ich habe bereits ein wenig gegoogelt, wo NSPredicates empfohlen werden, wobei in der Doku von Parse steht, dass man die nicht braucht, sondern einfach mit PFQueries arbeiten kann.
    Ich habe bisher noch nie mit Suchen gearbeitet und wenn ich improvisieren würde, dann würde es vermutlich gehen aber nicht sehr sauber.

    Danke, LG
  • Okay, danke, so habe ich mir das auch gedacht.

    Thyraz schrieb:

    Da Queries bei Parse ja nicht endlos kostenlos sind,
    Meinst Du, weil jeder query ein request ist und ich nur 30/sekunde senden kann? Eben das war auch der Nachteil, den ich mir gedacht habe, ich hatte gehofft, parse bietet eine etwas bessere Lösung dafür. Dennoch sind das 30 Keywords, die pro Sekunde gesucht werde können und das ist vorerst genug.

    Vielleicht werde ich auch die Suche filtern, sodass Wörter wie "ist" nicht als keyword gesehen werden. damit würde ich mir ein query sparen.
  • Ja ursprünglich wollte ich es so versuchen. Aber bisher habe ich es noch nicht hingekriegt.

    Damit könnte ich evtl. ein Query zusammenbauen.

    Bildschirmfoto 2015-08-25 um 15.35.32.png

    Das ist ein Auszug aus der Doku von Parse.
    Wie genau ich so ein query bauen könnte, weiß ich aber leider noch nicht.

    gritsch schrieb:

    also einfach mit OR verknüpfen
    Edit: das OR hast hast du ja selber angedeutet, habe ich erst mal überlesen :)
  • also mein Zwischenstand ist: ich habe jetzt mit einem Query alle objekte mit den passenden Keywords auf das Gerät bekommen.
    Enthält ein Objekt jetzt aber 4 von 4 Keywords, lädt er das Objekt jetzt 4 mal runter. Das ist natürlich nicht so gut, da es sinnloser traffic ist, auch wenn es nicht soo viel ist außerdem kann ich so nicht regeln, wie viele der Ergebnisse er runterladen soll. Denn alle geht natürlich nicht (falls es ein keyword ist, das häufig genutzt wird, lädt er dann viel zu viel)

    Ist Cloudcode wirklich die einzige Lösung das zu regeln? wollte mich damit jetzt nicht wirklich beschäftigen (muss ich wohl wenn es nicht anders geht)
  • asteiger schrieb:

    also mein Zwischenstand ist: ich habe jetzt mit einem Query alle objekte mit den passenden Keywords auf das Gerät bekommen.
    Enthält ein Objekt jetzt aber 4 von 4 Keywords, lädt er das Objekt jetzt 4 mal runter. Das ist natürlich nicht so gut, da es sinnloser traffic ist, auch wenn es nicht soo viel ist außerdem kann ich so nicht regeln, wie viele der Ergebnisse er runterladen soll. Denn alle geht natürlich nicht (falls es ein keyword ist, das häufig genutzt wird, lädt er dann viel zu viel)

    Ist Cloudcode wirklich die einzige Lösung das zu regeln? wollte mich damit jetzt nicht wirklich beschäftigen (muss ich wohl wenn es nicht anders geht)
    Funktionieren tut es schon, aber effizient ist es nicht. So hat man mehr Traffic und die Logik muss man dann auch am Client machen. Außerdem hat man am Server mehr Leistung und nicht begrenzten Akku. Das muss man abwägen wie komplex deine Logik ist und wie oft man einen Network Request macht.
    Stell dir vor, du möchtest die gleiche App auf Android oder Windows portieren, dann musst du die ganze Logik dort auch noch einmal implementieren. Das ist ein weiterer Nachteil.
  • ok ich habe mir Cloudcode angeguckt. Es ist in der Doku an einem Beispiel gezeigt. Ich denke ich kriege das wohl hin.
    Nach dem ich ein Query in der Cloud gemacht habe, muss ich es noch sortieren. Wie würde dass denn am effizientesten gehen? Auch hier wüsste ich, wie es möglich wäre, aber es wäre wahrscheinlich nicht gerade sauber.
  • Vielleicht kann mir jemand dabei helfen. Ich möchte für jedes keyword ein query machen (im cloudcode ist das ja nicht schlimm oder?)

    Ich habe aber keine Ahnung von JavaScript. Ich habe bis jetzt das hier, also nur ein query

    JavaScript-Quellcode: main.js

    1. Parse.Cloud.define("searchKeyword", function(request, response){
    2. var arrayLength = request.params.keywords.length;
    3. var resultArray = Array;
    4. for (var i = 0; i < arrayLength; i++) {
    5. /* Lese alle Keywords aus der Spalte Keywords aus der Table Answers aus */
    6. var query = new Parse.Query("Answers");
    7. query.equalTo("keywords", request.params.keywords[i]);
    8. query.find({
    9. success:function(results) {
    10. resultArray.push(results);
    11. },
    12. error: function() {
    13. }
    14. });
    15. }
    16. response.success(resultArray);
    17. });
    Alles anzeigen

    Am Ende seht ihr, dass ich alle Ergebnisse zurückgebe, ohne sie zu sortieren. Das sortieren ergänze ich noch, aber erst muss ich das zum laufen bringen.
    Wenn ich die For Schleife in der App nutze, also nur einen String übergebe, geht alles, aber die For schleife muss ja auch im Cloudcode stattfinden.

    Also das Problem ist, dass ich nur ein leeres Array zurückbekomme.

    Es ist jetzt das erste mal, dass ich mit JavaScript arbeite
  • msch schrieb:

    Beachte das Cloud Code Queries async sind.
    Um einen Counter, der mitzählt wie oft das Keyword vorkommt, wirst du nicht herumkommen. Danach kannst du auch am Schluss sortieren.
    ok, wegen dem async habe ich schon was versucht, was aber komischerweise nicht geklappt hat.
    Ich kann es morgen auch mal posten.

    Nun gut, das mit dem Counter sollte ich hinkriegen, das einzige ist halt, dass ich das in einer fremden Programmiersprache machen muss
  • Ich habe es fast geschafft. Ich weiß nur nicht wie ich den Counter einbauen soll.
    Ich habe an ein dictionary gedacht.
    Leider wusste ich nicht genau wie das mit Dictionaries in JavaScript geht. So habe ich es versucht.

    zur Erklärung:

    counter: integer, der dafür sorgt, dass der code nur im letzten Query ausgeführt wird
    arrayLength: Anzahl der Keywords mit denen gesucht wurde
    dict: mein Dictionary, dass ich als Counter nutzen wollte
    contentArray: Alle gefundenen Ergebnisse in einem Array (manche auch doppelt)

    So habe ich es versucht:

    JavaScript-Quellcode

    1. if(counter == arrayLength) {
    2. for (var y = 0; y < contentArray.length; y++) {
    3. if (dict[contentArray[y]] == undefined) {
    4. dict[contentArray[y]] = 0;
    5. }
    6. dict[contentArray[y]].value++;
    7. }
    8. response.success(dict);
    9. }


    ich habe dabei folgende Grundlagen beachtet:


    JavaScript-Quellcode

    1. dictionary[key] = value;
    2. dictionary[key].value = ...

    Aber es geht nicht. Es gibt auch keine Fehlermeldung.

    Das ist der Output der Konsole meiner App:

    Quellcode

    1. ( )
    Vielleicht liegt es auch einfach daran, dass ich heute den ganzen Tag an JavaScript gesessen habe und jetzt einfach keine Fehler mehr erkenne.

    LG
  • Der Dictionay Quellcode Nr1 passt.
    Da der Output der Konsole leer ist, denke ich das eine Query vielleicht nicht richtig ausgeführt wird.
    Hast du verschachtelte Abfragen oder Queries innerhalb von Schleifen? Schau dir mal Promises an.
    Wie gesagt, Abfragen in Cloud Code sind immer async.
  • Das ist ja das Problem.
    Als kleine nebeninfo: ich hab bereits versucht ein assoziatives Array zu nutzen, aber das war auch leer. Hört sich zwar so an, als hättest du Recht, ist aber nicht so.
    Ich habe mir contentArray auch schon mal testweise als response.success ausgeben lassen und habe da alle Ergebnisse wie geplant herausbekommen.
    Das sie async sind habe ich auch schon beachtet, sonst würde es ja nicht funktionieren.

    Also muss der Fehler praktisch im dictionary liegen.
    Ich kann meinen ganzen Code noch Einmal posten:

    JavaScript-Quellcode

    1. Parse.Cloud.define("searchKeyword", function(request, response){
    2. var arrayLength = request.params.keywords.length;
    3. var resultArray = new Array;
    4. var contentArray = new Array;
    5. var counter = 0;
    6. var counterArray = new Array;
    7. var dict = [];
    8. var indexCounter = 0;
    9. for (var i = 0; i < arrayLength; i++) {
    10. var query = new Parse.Query("Answers");
    11. query.equalTo("keywords", request.params.keywords[i]);
    12. query.find({
    13. success:function(results) {
    14. counter++;
    15. resultArray.push(results);
    16. for (var x = 0; x < results.length; x++) {
    17. var result = results[x];
    18. contentArray[indexCounter] = result;
    19. indexCounter++;
    20. }
    21. if(counter == arrayLength) {
    22. for (var y = 0; y < contentArray.length; y++) {
    23. if (dict[contentArray[y]] == undefined) {
    24. dict[contentArray[y]] = 0;
    25. }
    26. dict[contentArray[y]].value++;
    27. }
    28. response.success(contentArray);
    29. }
    30. },
    31. error: function() {
    32. counter++;
    33. if (counter == arrayLength) {
    34. response.success(counterArray);
    35. }
    36. }
    37. });
    38. }
    39. });
    Alles anzeigen
  • Hab mir gerade den Code angeschaut.

    Quellcode

    1. dict["key"].value++;
    funktioniert nicht
    In der Error Function solltest du auch response.error zurückgeben.

    Ich kann dir nur empfehlen den Algorithmus lokal oder auf jsfiddle mit Dummydaten zu testen.