<p>This probably happens because you're using the <code>.search()</code> param to query for the existing review entry, which means that Craft will look in the <em>search index</em> to try and find an entry matching the review ID.</p>
<p>The problem is that the search index isn't necessarily always up to date with the latest entry data, since Craft updates the search index asynchronously via a <a href="https://craftcms.com/docs/4.x/extend/queue-jobs.html" rel="nofollow noreferrer">queue job</a>. In general, you should never rely on the search index for mission critical logic like this.</p>
<p><strong>To fix the issue, query by the <code>reviewId</code> field directly instead of using <code>.search()</code>, i.e.:</strong></p>
<pre class="lang-php prettyprint-override"><code>$entries = Entry::find()-&gt;section('reviews')-&gt;reviewId($id)-&gt;all();
</code></pre>

CC BY-SA 4.0
2022-11-06T01:14:36.263Z
As I understand it, using search() also significantly reduces the speed of processing my code. The error has been fixed + the code has become faster to work out. Thanks man)
Dimi
CC BY-SA 4.0
2022-11-06T01:47:44.533Z
Yeah, `.search()` is comparatively slow compared to querying on field values directly. Use it for actual searches only :)
Mats Mikkel Rummelhoff
CC BY-SA 4.0
2022-11-06T01:51:35.430Z
@Dimi Also, re: performance you might consider using `.exists()` instead of `.all()`, which is a much cheaper query – i.e. `$reviewExists = Entry::find()->section('reviews')->search('reviewId::'.$id)->exists();` ... `if (!$reviewExists) { ...`
Mats Mikkel Rummelhoff
CC BY-SA 4.0
2022-11-09T13:35:02.547Z
Yes, this construction i think best solution: $reviewExists = Entry::find()->section('reviews')->reviewId($id)->exists(); I'm just learning the system. Your advice is very helpful. Thanks again
Dimi
CC BY-SA 4.0
2022-11-09T15:19:32.360Z
By the way, I created a separate question about the catalog filter. I think that there just need to use search
Dimi
CC BY-SA 4.0
2022-11-05T21:06:32.647Z
2022-11-05T21:24:57.203Z
2022-11-05T21:24:57.203Z
Mats Mikkel Rummelhoff
<p>Please help me solve the problem. Task: to organize the unloading of reviews from a third-party service that gives reviews in the form of xml.</p>
<p>I solved this problem through the module. I did all the necessary actions to process the received data in the controller. Here is the controller code:</p>
<pre><code>&lt;?php
namespace modules\reviews\controllers;

use Craft;
use craft\web\Controller;
use craft\elements\Entry;


class ReviewsController extends Controller
{

    protected array|bool|int $allowAnonymous = true;

    public function actionStart() {

        $xml=&quot;XMLURL&quot;;
        $xml= simplexml_load_file($xml);

        foreach($xml-&gt;reviews-&gt;review as $review){

            $id = $review-&gt;attributes()-&gt;id;
            $text= $review-&gt;text;

            $entries = Entry::find()-&gt;section('reviews')-&gt;search('reviewId::'.$id)-&gt;all();

            if(count($entries) == 0){
                $entry = new Entry();
                $entry-&gt;sectionId = 10;
                $entry-&gt;enabled = true;
                $entry-&gt;title = &quot;Review ID&quot;.$id;
                $entry-&gt;setFieldValues([
                    'reviewId' =&gt; $id
                    'reviewText' =&gt; $text,
                ]);
                $success = Craft::$app-&gt;elements-&gt;saveElement($entry);
                if (!$success) {
                      Craft::error('Couldn’t save the review ID&quot;'.$id.'&quot;', __METHOD__);
                }
            }

        }
        return &quot;Ready&quot;;
    }
}
</code></pre>
<p>That's what my code does - it receives a list of reviews from a third-party service, runs through the reviews that are in my database. If the code finds some new review, it adds it to the database.</p>
<p>Checking for a new review will be carried out by the created simple field &quot;reviewId&quot;. At least that's how it should work. And it works, but not when it needs to.</p>
<p>In the file routes.php I made CRAFT systems so that my module worked out by the URL of my site: site.com/reviews/update . At the hoster in CRON, I set a timer for processing an HTTP request (1 time per hour should be executed).</p>
<p>And here something strange happens.</p>
<p>If I personally open my URL in the browser, then everything works out as intended! But for some reason CRON reacts strangely to if(count($entries) == 0). A new review is added to the database, but when the CRON task is run again for the condition if(count($entries) == 0) for the same review returns TRUE. As if this new comment was not added to the database in the previous task. But this is not the case, it is added to the database normally. In this case, my database is filled with a bunch of identical comments in the morning. What could be the problem? Help plz</p>

CC BY-SA 4.0
2022-11-05T19:02:40.680Z
What does the cron job command look like?
Mats Mikkel Rummelhoff
CC BY-SA 4.0
2022-11-05T19:19:52.933Z
Oh, I don't know. In the hosting control panel, it looks like a list of tasks that can be performed on a timer. I have already selected "execute HTTP request once per hour"
Dimi
CC BY-SA 4.0
2022-11-05T19:22:12.887Z
I also noticed such a nuance. If I am logged in to the system, then everything goes fine according to the cron task. Does not add duplicates. But if I go to sleep, for example, I see duplicates in the morning.
Dimi
<craft3>
If is not triggered by a cron http request. Why?
# If is not triggered by a cron http request. Why?

(Asked by: username_0 on 2022-11-05)

Please help me solve the problem. Task: to organize the unloading of reviews from a third-party service that gives reviews in the form of xml.
I solved this problem through the module. I did all the necessary actions to process the received data in the controller. Here is the controller code:
reviews->review as $review){

            $id = $review->attributes()->id;
            $text= $review->text;

            $entries = Entry::find()->section('reviews')->search('reviewId::'.$id)->all();

            if(count($entries) == 0){
                $entry = new Entry();
                $entry->sectionId = 10;
                $entry->enabled = true;
                $entry->title = "Review ID".$id;
                $entry->setFieldValues([
                    'reviewId' => $id
                    'reviewText' => $text,
                ]);
                $success = Craft::$app->elements->saveElement($entry);
                if (!$success) {
                      Craft::error('Couldn’t save the review ID"'.$id.'"', __METHOD__);
                }
            }

        }
        return "Ready";
    }
}

That's what my code does - it receives a list of reviews from a third-party service, runs through the reviews that are in my database. If the code finds some new review, it adds it to the database.
Checking for a new review will be carried out by the created simple field "reviewId". At least that's how it should work. And it works, but not when it needs to.
In the file routes.php I made CRAFT systems so that my module worked out by the URL of my site: site.com/reviews/update . At the hoster in CRON, I set a timer for processing an HTTP request (1 time per hour should be executed).
And here something strange happens.
If I personally open my URL in the browser, then everything works out as intended! But for some reason CRON reacts strangely to if(count($entries) == 0). A new review is added to the database, but when the CRON task is run again for the condition if(count($entries) == 0) for the same review returns TRUE. As if this new comment was not added to the database in the previous task. But this is not the case, it is added to the database normally. In this case, my database is filled with a bunch of identical comments in the morning. What could be the problem? Help plz

**Tags:** craft3
> **Comments:**
> **username_1**: What does the cron job command look like?  
> **username_0**: Oh, I don't know. In the hosting control panel, it looks like a list of tasks that can be performed on a timer. I have already selected "execute HTTP request once per hour"  
> **username_0**: I also noticed such a nuance. If I am logged in to the system, then everything goes fine according to the cron task. Does not add duplicates. But if I go to sleep, for example, I see duplicates in the morning.  

---

## 1 answers

### Answer by username_1 on 2022-11-05. Score: 1 | Accepted answer

This probably happens because you're using the .search() param to query for the existing review entry, which means that Craft will look in the search index to try and find an entry matching the review ID.
The problem is that the search index isn't necessarily always up to date with the latest entry data, since Craft updates the search index asynchronously via a queue job. In general, you should never rely on the search index for mission critical logic like this.
To fix the issue, query by the reviewId field directly instead of using .search(), i.e.:
$entries = Entry::find()->section('reviews')->reviewId($id)->all();

> **Comments:**
> **username_0**: As I understand it, using search() also significantly reduces the speed of processing my code. The error has been fixed + the code has become faster to work out. Thanks man)  
> **username_1**: Yeah, `.search()` is comparatively slow compared to querying on field values directly. Use it for actual searches only :)  
> **username_1**: @Dimi Also, re: performance you might consider using `.exists()` instead of `.all()`, which is a much cheaper query – i.e. `$reviewExists = Entry::find()->section('reviews')->search('reviewId::'.$id)->exists();` ... `if (!$reviewExists) { ...`  
> **username_0**: Yes, this construction i think best solution: $reviewExists = Entry::find()->section('reviews')->reviewId($id)->exists(); I'm just learning the system. Your advice is very helpful. Thanks again  
> **username_0**: By the way, I created a separate question about the catalog filter. I think that there just need to use search  

---

